简体   繁体   English

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

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

After reading about the quick sort algorithm, I decided to write my own implementation before looking at any code. 在阅读了快速排序算法之后,我决定在查看任何代码之前编写自己的实现。 The code below is what I came up with. 下面的代码是我想出的。 Upon comparing my code with other implementations I have observed that rather than returning the sorted array from the quick sort function, other implementations tend to take advantage of a list's mutability and simply run the function on the unsorted array, which in turn will sort the array without having to reference the function call. 通过将我的代码与其他实现进行比较,我观察到,与从快速排序函数返回排序后的数组相比,其他实现倾向于利用列表的可变性并仅在未排序的数组上运行该函数,从而对数组进行排序无需引用函数调用。 I am curious about the space time comparison with my code and the code from the book I am using, which I have provided below. 我对与我的代码以及我正在使用的书中的代码进行时空比较感到好奇,下面将提供这些代码。 I am assuming that in terms of time the algorithims perform rather similarly, maybe the concatenation operation I am performing has a negative impact? 我假设就算法而言,在时间方面,我执行的串联操作可能会产生负面影响吗? In terms of space, since I am not modifying the input array directly, I am assuming that I am creating/ returning a new array which is obviously inefficient, and important because the main advantage of quick sort over merge sort is the saved space. 在空间方面,由于我没有直接修改输入数组,因此我假设我正在创建/返回一个显然效率不高的新数组,并且很重要,因为快速排序优于合并排序的主要优点是节省了空间。 Overall I am just looking for some additional insight and any way to improve my algorithm's efficiency. 总的来说,我只是在寻找一些其他的见识,以及寻求任何方法来提高算法的效率。

My code: 我的代码:

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)])

The book I am using, Problem Solving With Algorithms and Data Structures Using Python By Brad Miller and David Ranum, provides this quick sort code: 我正在使用的这本书(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)

This is nice code. 这是不错的代码。

Compared to a quicksort version that is done in place (using only one array), yours may be a bit slower because of the copy/concatenation. 与就地完成的快速排序版本(仅使用一个数组)相比,由于复制/串联,您的速度可能会慢一些。

Quicksort performances rely a lot on the choice of the pivot. Quicksort的表演很大程度上依赖于枢轴的选择。 By choosing the first element, there are some cases where your code runs in quadratic time, for example while sorting an already sorted array. 通过选择第一个元素,在某些情况下您的代码将以二次时间运行,例如,在对已经排序的数组进行排序时。 The most known optimizations are: 最著名的优化是:

  • Choosing a better pivot, for example by applying Tukey's ninther (you avoid those worst cases almost certainly). 选择更好的枢轴,例如通过应用Tukey的ninther(几乎可以肯定地避免了最坏的情况)。
  • Performing an Insertion sort when the subarray is small enough (< 10 for example). 当子数组足够小时(例如,<10),执行插入排序。

Else, there are a few variants of quicksort which run faster, like 3-way quicksort using Bentley-McIlroy's sheme or dual-pivot quicksort (used to sort arrays of primitive in java). 另外,还有一些快速排序的变体,它们运行得更快,例如使用Bentley-McIlroy的sheme或双轴快速排序(用于对Java中的原始数组进行排序)的三向快速排序。 The Insertion speedup is still applicable for those. 插入加速仍然适用于那些。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM