今天和大家一起讨论快速排序,对于包含n个数的输入数组来说,快速排序是一种最坏情况时间复杂度为o(n * n)的排序算法。虽然最坏情况时间复杂度很差,但是快速排序通常是实际排序应用中最好的选择,因为它的平均性能非常好;它的期望时间复杂度为o(n lgn),而且o(n lgn)中隐含的常数因子非常小。另外,它还能进行原址排序,甚至在虚存环境中也能很好的工作。
快速排序的描述:
与归并排序一样,快速排序也使用了分治思想,下面是对一个典型的子数组A[p...r]进行快速排序的三步分治过程:
分解:数组A[p...r]被划分为两个(可能为空)子数组A[p...q - 1]和A[q + 1...r],使得A[p...q - 1]中的每一个元素都小于或等于A[q],而A[q]也小于等于A[q + 1...r]中的每一个元素。其中计算下标q也是划分过程的一部分。
解决:通过递归调用快速排序,对子数组A[p...q - 1]和A[q + 1...r]进行排序。
下面则分别实现quicksort.h和quicksort.c
#ifndef _QUICKSORT_H_ #define _QUICKSORT_H_ #define N 10 //接口声明 void Quicksort(int *data,int p,int r); int Partition(int *data,int p,int r); void print_array(int *data,int n); #endif
#include <stdio.h> #include <stdlib.h> #include "quicksort.h" static void swap(int *a,int *b) { int temp = 0; temp = *a; *a = *b; *b = temp; } void Quicksort(int *data,int p,int r) { int q = 0; if(p < r){ q = Partition(data,p,r); Quicksort(data,p,q - 1); Quicksort(data,q + 1,r); } } int Partition(int *data,int p,int r) { int i = p - 1; int x = data[r]; int j = 0; for(j = p;j <= r - 1;++j){ if(data[j] < x){ i = i + 1; swap(&data[i],&data[j]); } } swap(&data[i + 1],&data[r]); return i + 1; } void print_array(int *data,int n) { int i = 0; for(i = 0;i < n;++i){ printf("%5d",data[i]); } printf("\n"); }
#include <stdio.h> #include <stdlib.h> #include "quicksort.h" int main(int argc ,char **argv) { int data[N]; int i = 0; srand(time(0)); for(i = 0;i < N;++i){ data[i] = rand() % 100; } printf("排序前:\n"); print_array(data,N); Quicksort(data,0,N - 1); printf("排序后:\n"); print_array(data,N); return 0; }
快速排序的性能分析:
快速排序的运行时间依赖于划分是否平衡,而平衡与否又依赖于用于划分的元素。如果划分是平衡的,那么快速排序算法性能与归并排序一样。如果划分是不平衡的,那么快速排序的性能就接近于插入排序了。
最坏情况划分:当划分产生的两个子问题分别包含了n - 1个元素和0个元素时,快速排序的最坏情况发生了。不妨假设算法的每一次递归调用都出现了这种不平衡划分。划分操作的时间复杂度是o(n)。由于对一个大小为0的数组进行递归调用会直接返回,因此T(0) = O(1),于是算法的运行时间的递归式可以表示为:
T(n)= T(n - 1)+T(0)+ o(n)= T(n - 1)+o(n)
利用代入法可以直接得到递归式T(n)= o(n * n)
最好情况分析:在可能的最平衡的划分中,Partition得到的两个子问题的规模都不大于n / 2,这是因为其中一个子问题的规模为[n / 2],则另一个子问题的规模为[n / 2] - 1。在这种情况下,排序的性能非常好,此时,算法运行时间的递归式为;
T(n) = 2T(n / 2)+ o(n)
根据定理,上述递归式的解为T(n) = o(n lgn)。