快速排序
- 无需额外的空间,直接在原有的序列上完成排序,相对的是归并排序,在合并的时候需要额外的空间
- divide: 选取一个轴,依据轴将数组划分为大于轴和小于轴两部分
- 递归主要是为了找到划分点的下标
- 无需进行合并,因为是在原数组上进行的排序
伪代码
QUICKSORT(A, p, r)
if p < r
q = PARTITION(A, p, r)
QUICKSORT(A, p, q-1)
QUICKSORT(A, q+1, r)
PARTITION(A, p, r)
x = A[r]
i = p - 1
for j=p to r-1
if A[j] <= x
i = i + 1
exchange A[i] with A[j]
return i+1
python
def partition(A, p, r):
x = A[r]
i = p - 1
j = p
while j <= r:
if A[j] <= x:
i = i + 1
temp = A[i]
A[i] = A[j]
A[j] = temp
j = j + 1
return i
def quick_sort(A, p, r):
if p < r:
q = partition(A, p, r)
quick_sort(A, p, q-1)
quick_sort(A, q+1, r)
def main():
A = [2, 8, 7, 1, 3, 5, 6, 4]
print(A)
quick_sort(A, 0, 7)
print(A)
if __name__ == "__main__":
main()
c++
#include <iostream>
using namespace std;
int partition(int A[], int p, int r)
{
int x = A[r];
int temp;
int i = p-1;
int j = p;
for (; j<=r; j++)
{
if (A[j]<=x)
{
i++;
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
return i;
}
void quick_sort(int A[], int p, int r)
{
if (p<r)
{
int q = partition(A, p, r);
quick_sort(A, p, q-1);
quick_sort(A, q+1, r);
}
}
int main()
{
int A[] = {2, 8, 7, 1, 3, 5, 6, 4};
for (int i=0; i<=7; i++)
{
cout << A[i] << " ";
}
cout << endl;
quick_sort(A, 0, 7);
for (int i=0; i<=7; i++)
{
cout << A[i] << " ";
}
cout << endl;
return 0;
}
算法分析
快排是一个分治策略,快排算法的性能依赖于划分的平衡性,划分是否平衡依赖于划分点的选取
- 最坏的情况:数组有序,无论正反,划分一边为n-1,另一边是0,时间复杂度均为 $ heta(n^2)$,但是插入排序此时为$ heta(n)$
- 最好的情况是均分,两侧数量相同,时间复杂度 $ heta(nlg{n})$