排序算法之快速排序
看题目:
快速排序(英语:Quicksort),又称划分交换排序(partition-exchange sort),通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
总体思路:
1.划分交换排序:从数列中挑出一个元素,称为"基准"(pivot),通常选取每一部分的第一个元素作为基准。 重新排序数列,一右一左的将所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
2.进行递归:递归的(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
3.结束递归:递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
上代码:
1 def quick_sort(alist, first, last): 2 """快速排序""" 3 if first >= last: # 递归退出的条件 4 return 5 6 mid = alist[first] # 设定起始的基准元素 7 low = first # low为序列从开始位置由左向右移动的游标 8 high = last # hight为序列从末尾位置由右向左的游标 9 10 while low < high: 11 # 如果low与high未重合,high(右边)指向的元素大于等于基准元素,则high向左移动,此处我们的目的是找到比基准小的元素。 12 while low < high and alist[high] >= mid: 13 high -= 1 14 15 # 走到此位置时,high指向一个比基准元素小的元素,将high指向的元素放到low的位置上,此时high指向的位置空着。 16 alist[low] = alist[high] 17 # 接下来移动low找到符合条件的元素--比基准元素大的元素--放在high位置处。 18 # 如果low与high未重合,low指向的元素比基准元素小,则low向右移动,此处我们的目的是找到比基准大的元素。 19 while low < high and alist[low] < mid: 20 low += 1 21 alist[high] = alist[low] # 走到此位置时,low指向一个比基准大的元素,将low指向的元素放到high空着的位置上,此时low指向的位置空着。 22 # 之后进行下一个循环,移动high找到符合条件的元素--比基准小的元素--放到low位置处。 23 24 # 退出循环后,low与high重合,此时所指位置为基准元素的正确位置,左边的元素都比基准元素小,右边的元素都比基准元素大 25 alist[low] = mid # 将基准元素放到该位置 26 27 # 开始递归 28 # 将基准元素左边的子序列进行快速排序 29 quick_sort(alist, first, low - 1) # start:0 low-1 元基准元素靠左边一位 30 # 对基准元素右边的子序列进行快速排序 31 quick_sort(alist, low + 1, last) # low+1 : 原基准元素靠右一位 end: 最后 32 33 34 if __name__ == '__main__': 35 # xiaogang = Solution() 36 ll = [54, 26, 93, 17, 77, 31, 44, 55, 20] 37 n = len(ll) 38 quick_sort(ll, 0, n - 1) 39 print(ll)
时间复杂度:大部分情况下为O(nlogn),极少数情况下为O(n2)。
空间复杂度:O(logn)~O(n)。相当于以时间换空间。
快速排序算法,相对于其他排序算法最快,相对于归并排序所要花费的辅助空间较少,常用。