Самый быстрый способ сортировки в Python - PullRequest
13 голосов
/ 04 октября 2010

Какой самый быстрый способ сортировки массива целых чисел больше 0 и меньше 100000 в Python?Но не используя встроенные функции, такие как sort.

Я смотрю на возможность комбинировать 2 спортивные функции в зависимости от размера ввода.

Ответы [ 9 ]

15 голосов
/ 04 октября 2010

Если вас интересует асимптотическое время , то подсчет сортировки или радикальная сортировка обеспечивают хорошую производительность.

Однако если вас интересует время настенных часов потребуется сравнить производительность между различными алгоритмами, используя ваши конкретные наборы данных , поскольку разные алгоритмы работают по-разному с разными наборами данных.В этом случае всегда стоит попробовать быструю сортировку:

def qsort(inlist):
    if inlist == []: 
        return []
    else:
        pivot = inlist[0]
        lesser = qsort([x for x in inlist[1:] if x < pivot])
        greater = qsort([x for x in inlist[1:] if x >= pivot])
        return lesser + [pivot] + greater

Источник: http://rosettacode.org/wiki/Sorting_algorithms/Quicksort#Python

7 голосов
/ 04 октября 2010

Поскольку вы знаете диапазон чисел, вы можете использовать Отсчет сортировки , который будет линейным по времени.

3 голосов
/ 05 октября 2010

Radix сортировка теоретически выполняется за линейное время (время сортировки увеличивается примерно пропорционально размеру массива), но на практике Quicksort, вероятно, больше подходит, если только вы не сортируете абсолютно массивные массивы.

Если вы хотитечтобы сделать быструю сортировку немного быстрее, вы можете использовать сортировку вставкой], когда размер массива становится небольшим.

Вероятно, было бы полезно понять концепции алгоритмической сложности и нотации Big-O.

2 голосов
/ 04 октября 2010

Ранние версии Python использовали гибрид samplesort (вариант быстрой сортировки с большим размером выборки) и двоичную сортировку вставкой в ​​качестве встроенного алгоритма сортировки.Это оказалось несколько нестабильным.S0, начиная с Python 2.3 и далее, использует алгоритм adaptive mergesort.

Порядок слияния (средний) = O(nlogn).Порядок слияния (худший) = O(nlogn).Но Порядок быстрой сортировки (худший) = n * 2

, если вы используете list=[ .............. ]

list.sort() использует mergesort algorithm.

Для сравнения алгоритма сортировки вы можетечитать вики

Для подробного сравнения comp

1 голос
/ 08 марта 2017

Возможно, я немного опоздаю на шоу, но есть интересная статья, в которой сравниваются разные виды на https://www.linkedin.com/pulse/sorting-efficiently-python-lakshmi-prakash

Один из основных выводов заключается в том, что хотя сортировка по умолчанию работает отлично, мы можем сделать немного лучше с скомпилированной версией быстрой сортировки. Это требует пакета Numba.

enter image description here

Вот ссылка на репозиторий Github: https://github.com/lprakash/Sorting-Algorithms/blob/master/sorts.ipynb

1 голос
/ 05 октября 2010

Мы можем использовать сортировку счетчиков, используя словарь, чтобы минимизировать использование дополнительного пространства, а также сохранить время выполнения на низком уровне. Сортировка счетчика намного медленнее для небольших размеров входного массива из-за накладных расходов реализации Python и C. Сортировка счетчика начинает обгонять обычную сортировку, когда размер массива (COUNT) составляет около 1 млн.

Если вам действительно нужны огромные ускорения для входов меньшего размера, реализуйте сортировку счетчиков в C и вызывайте ее из Python.

(Исправлена ​​ошибка, которую Аарон (+1) помог поймать ...) Приведенная ниже реализация только на python сравнивает 2 подхода ...

import random
import time

COUNT = 3000000

array = [random.randint(1,100000) for i in range(COUNT)]
random.shuffle(array)

array1 = array[:]

start = time.time()
array1.sort()
end = time.time()
time1 = (end-start)
print 'Time to sort = ', time1*1000, 'ms'

array2 = array[:]

start = time.time()
ardict = {}
for a in array2:
    try:
        ardict[a] += 1
    except:
        ardict[a] = 1

indx = 0
for a in sorted(ardict.keys()):
    b = ardict[a]
    array2[indx:indx+b] = [a for i in xrange(b)]
    indx += b

end = time.time()
time2 = (end-start)
print 'Time to count sort = ', time2*1000, 'ms'

print 'Ratio =', time2/time1
0 голосов
/ 16 декабря 2016

@ fmark Некоторый сравнительный анализ реализации сортировки слиянием Python, которую я написал для быстрой сортировки Python от http://rosettacode.org/wiki/Sorting_algorithms/Quicksort#Python и сверху ответ.

  1. Размер списка и размер чисел в списке не имеет значения

сортировка слиянием выигрывает, однако она использует встроенную функцию int () для пола

import numpy as np
x = list(np.random.rand(100))


# TEST 1, merge_sort 
def merge(l, p, q, r):
    n1 = q - p + 1
    n2 = r - q
    left = l[p : p + n1]
    right = l[q + 1 : q + 1 + n2]

    i = 0
    j = 0
    k = p
    while k < r + 1:
        if i == n1:
            l[k] = right[j]
            j += 1
        elif j == n2:
            l[k] = left[i]
            i += 1
        elif  left[i] <= right[j]:
            l[k] = left[i]
            i += 1
        else:
            l[k] = right[j]
            j += 1
        k += 1

def _merge_sort(l, p, r):
    if p < r:
        q = int((p + r)/2)
        _merge_sort(l, p, q)
        _merge_sort(l, q+1, r)
        merge(l, p, q, r)

def merge_sort(l):
    _merge_sort(l, 0, len(l)-1)

# TEST 2
def quicksort(array):
    _quicksort(array, 0, len(array) - 1)

def _quicksort(array, start, stop):
    if stop - start > 0:
        pivot, left, right = array[start], start, stop
        while left <= right:
            while array[left] < pivot:
                left += 1
            while array[right] > pivot:
                right -= 1
            if left <= right:
                array[left], array[right] = array[right], array[left]
                left += 1
                right -= 1
        _quicksort(array, start, right)
        _quicksort(array, left, stop)

# TEST 3
def qsort(inlist):
    if inlist == []: 
        return []
    else:
        pivot = inlist[0]
        lesser = qsort([x for x in inlist[1:] if x < pivot])
        greater = qsort([x for x in inlist[1:] if x >= pivot])
        return lesser + [pivot] + greater

def test1():
    merge_sort(x)

def test2():
    quicksort(x)

def test3():
    qsort(x)

if __name__ == '__main__':
    import timeit
    print('merge_sort:', timeit.timeit("test1()", setup="from __main__ import test1, x;", number=10000))
    print('quicksort:', timeit.timeit("test2()", setup="from __main__ import test2, x;", number=10000))
    print('qsort:', timeit.timeit("test3()", setup="from __main__ import test3, x;", number=10000))
0 голосов
/ 24 сентября 2013
def sort(l):
    p = 0
    while(p<len(l)-1):
        if(l[p]>l[p+1]):
            l[p],l[p+1] = l[p+1],l[p]
            if(not(p==0)):
                p = p-1
        else:
            p += 1
    return l

это алгоритм, который я создал, но он действительно быстрый. просто сделать сортировку (л) Я список, который вы хотите отсортировать.

0 голосов
/ 04 октября 2010

Встроенные функции лучше, но так как вы не можете их использовать, посмотрите на это:

http://en.wikipedia.org/wiki/Quicksort

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...