快速排序
-
一种交换排序
-
基本思想
首先,在待排序表L[1…n]中任取一个元素(通常取首元素)作为枢轴,记作pivot;
通过一趟排序将L分成两部分L[1…k-1]和L[k+1…n],其中L[1…k-1]的元素都小于pivot,L[k+1…n]都大于pivot,pivot放在了最终位置,这个过程称为一次划分;
然后分别递归地对两个子表重复上述过程,直至每部分内只有一个元素或空为止。
- 详细代码
C语言:
#include<stdio.h>
void QuickSort(int *A,int low,int high){
if(low<high){
int i=low;
int j=high;
int k=A[low];
while(i<j){
while(i<j&&A[j]>=k) --j;
A[i]=A[j]; //将右边比枢轴小的元素移动到左边
while(i<j&&A[i]<=k) ++i;
A[j]=A[i]; //将左边比枢轴大的元素移动到右边
}
A[i]=k;
// 递归调用
QuickSort(A, low, i - 1); // 排序k左边
QuickSort(A, i + 1, high); // 排序k右边
}
}
int main(){
int A[5]={1,4,2,9,7};
QuickSort(A,0,4);
for(int i=0;i<5;i++) printf("%d ",A[i]);
}
// Prints "1 2 4 7 9"
Python语言:
def quicksort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2] #取整
left = [x for x in arr if x < pivot] #比pivot小的元素放在左边
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quicksort(left) + middle + quicksort(right)
print(quicksort([3,6,8,10,1,2,1]))
# Prints "[1, 1, 2, 3, 6, 8, 10]"
- 空间复杂度
递归操作需要借助一个递归工作栈
最好情况下,空间复杂度=递归层数=二叉树的高度= l o g 2 {log_2} log2n(左子树等于右子树)
最坏情况下,空间复杂度=递归层数=二叉树的高度=n
平均情况下,空间复杂度=递归层数=二叉树的高度= l o g 2 {log_2} log2n
- 时间复杂度
时间复杂度=O(n×递归层数)
最好O(n l o g 2 {log_2} log2n),最坏O( n 2 {n^2} n2)
当排列表有序时递归层数为n,此时快速排序最慢
- 快速排序为不稳定的排序
不稳定因为存在交换。{3,2,2},经过快排后变成{2,2,3},2的相对位置发生了变化
- 快速排序是最优秀的内部排序