繁体   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