簡體   English   中英

如何改善快速排序算法(Python)

[英]How can I improve my quick sort algorithm (Python)

在閱讀了快速排序算法之后,我決定在查看任何代碼之前編寫自己的實現。 下面的代碼是我想出的。 通過將我的代碼與其他實現進行比較,我觀察到,與從快速排序函數返回排序后的數組相比,其他實現傾向於利用列表的可變性並僅在未排序的數組上運行該函數,從而對數組進行排序無需引用函數調用。 我對與我的代碼以及我正在使用的書中的代碼進行時空比較感到好奇,下面將提供這些代碼。 我假設就算法而言,在時間方面,我執行的串聯操作可能會產生負面影響嗎? 在空間方面,由於我沒有直接修改輸入數組,因此我假設我正在創建/返回一個顯然效率不高的新數組,並且很重要,因為快速排序優於合並排序的主要優點是節省了空間。 總的來說,我只是在尋找一些其他的見識,以及尋求任何方法來提高算法的效率。

我的代碼:

from random import randint

def quick(arr):
  if len(arr) == 1:
    return arr
  else:

    pivot = arr[0]
    R = len(arr)-1
    L = 1

    while L <= len(arr)-1 and R >= 1:
        if R == L:
            if arr[0] > arr[R]:
                arr[0], arr[R] = arr[R], arr[0]
            break
        if arr[R] >= pivot:
            R = R - 1
            continue
        if arr[L] <= pivot:
            L = L + 1
            continue
        arr[L], arr[R] = arr[R], arr[L]
    return quick(arr[:R]) + quick(arr[R:])

print quick([randint(0,1000) for i in range(1000)])

我正在使用的這本書(Brad Miller和David Ranum着的《使用Python解決算法和數據結構問題》)提供了以下快速排序代碼:

def quickSort(alist):
  quickSortHelper(alist,0,len(alist)-1)

def quickSortHelper(alist,first,last):
  if first<last:

   splitpoint = partition(alist,first,last)

   quickSortHelper(alist,first,splitpoint-1)
   quickSortHelper(alist,splitpoint+1,last)


def partition(alist,first,last):
  pivotvalue = alist[first]

  leftmark = first+1
  rightmark = last

 done = False
 while not done:

   while leftmark <= rightmark and alist[leftmark] <= pivotvalue:
     leftmark = leftmark + 1

   while alist[rightmark] >= pivotvalue and rightmark >= leftmark:
     rightmark = rightmark -1

     if rightmark < leftmark:
       done = True
     else:
       temp = alist[leftmark]
       alist[leftmark] = alist[rightmark]
       alist[rightmark] = temp

 temp = alist[first]
 alist[first] = alist[rightmark]
 alist[rightmark] = temp

return rightmark

# alist = [54,26,93,17,77,31,44,55,20]
# quickSort(alist)
# print(alist)

這是不錯的代碼。

與就地完成的快速排序版本(僅使用一個數組)相比,由於復制/串聯,您的速度可能會慢一些。

Quicksort的表演很大程度上依賴於樞軸的選擇。 通過選擇第一個元素,在某些情況下您的代碼將以二次時間運行,例如,在對已經排序的數組進行排序時。 最著名的優化是:

  • 選擇更好的樞軸,例如通過應用Tukey的ninther(幾乎可以肯定地避免了最壞的情況)。
  • 當子數組足夠小時(例如,<10),執行插入排序。

另外,還有一些快速排序的變體,它們運行得更快,例如使用Bentley-McIlroy的sheme或雙軸快速排序(用於對Java中的原始數組進行排序)的三向快速排序。 插入加速仍然適用於那些。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM