快速排序:
基本概念:
- 把所有的元素分成小的元素和大的元素两类。所有小的元素要小于所有大的元素。
- 重新把这些小的元素排列到所有大的元素前面。
- 再把所有小的元素和所有大的元素分别递归来重新排列。
-----------------------------------------------
所有元素
-----------------------------------------------
-----------------------------------------------
所有小的元素 | | 所有大的元素
-----------------------------------------------
具体实现过程:
- 让数组中的第一个数成为主值(pivot value) x ,也叫划分值(split value)
- 所有小的元素应当小于x
- 所有大的元素应当大于等于x
数组排序前:
first last
-----------------------------------------------
x | ?
-----------------------------------------------
数组排序后:
first splitpoint last
-----------------------------------------------
<x |x| >=x
-----------------------------------------------
伪代码:
主体函数quickSort只为实现递归逻辑。split函数才是实现排序当前数组。
def quickSort(A, first, last):
if first < last: #若>=,递归结束,排序完成
splitpoint = split(A, first, last)#返回splitpoint的索引值
quickSort(A, first, splitpoint-1)
quickSort(A, splitpoint+1, last)
def split(A, first, last):
splitpoint = first#split point的索引值
x = A[first]#保留split point的值
for k = first+1 to last do: #从第二个数开始遍历
if A[k] < x: #如果遍历到的数小于split point
A[splitpoint+1] <-> A[k]
splitpoint += 1
#循环结束,可以保证splitpoint索引本身以及左边都是小于x的数,而第一个数为x。
#此时,再把第一个数和splitspoint交换,这样就得到了由splitpoint分开的数组了。
A[first] <-> A[splitpoint]
return splitpoint
在循环中:
- A[first+1 … splitpoint]的元素 < x
- A[splitpoint+1 … k-1] 的元素>=x
- A[k … last]的元素还没有进行排序
划分步骤图解:
开始时:
first k last
-----------------------------------------------
x | ?
-----------------------------------------------
排序中:
first k sp k last
-----------------------------------------------
x | <x | >=x | ?
-----------------------------------------------
结束时:
first k sp last
-----------------------------------------------
x | <x | >=x
-----------------------------------------------
^_______交换__________^
算法分析:
- 最坏情况下:时间复杂度为O(n^2),因为每一对数值都会被比较一次。
- 平均情况下:类似二叉树,时间复杂度为O(nlogn)
在数组将近排好序时,插入排序最快,快速排序很慢。
此博客仅用于自我学习的记录,如有不当请指正。12/14/2021