快速排序(QuickSort)是冒泡排序的优化算法。
基本思想:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字比另一部分记录的关键字小,则可以分别对这两部分记录继续进行快速排序,以达到整个序列有序的目的。
枢轴(pivot):选取待排序列当中的一个关键字,然后想尽办法把它放到一个位置,使得它左边的值都比它小,右边的值都比它大,我们将这样的关键字成为枢轴(pivot)。
一般取待排序最左端的那个关键字为枢轴。
#include <stdio.h> #include <stdlib.h> void swap(int arr[] ,int i, int j) { int temp; temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } //将待排序的数组分为两个部分,枢轴左面的值都比枢轴值小,右面的值都比枢轴值大,函数返回值pivot为枢轴所在的位置 int Partition(int arr[], int low, int high) { int pivotkey; //枢轴值 pivotkey = arr[low]; //取待排序的第一个值为枢轴值 while(low < high) { while(low < high && arr[high] >= pivotkey) high--; swap(arr, low, high); // 将比枢轴记录小的记录交换到低端 while(low < high && arr[low] <= pivotkey) low++; swap(arr, low, high); //将比枢轴记录大的记录交换到高端 } return low; //返回枢轴所在的位置 } void QuickSort(int arr[], int low, int high) { int pivot; //枢轴值 if(low < high) { pivot = Partition(arr, low, high); //将待排序的数组分为两个部分,枢轴左面的值都比枢轴值小,右面的值都比枢轴值大,pivot为枢轴所在的位置 QuickSort(arr, low, pivot-1); //将枢轴值左面的 序列 重新快速排序 QuickSort(arr, pivot+1, high); //将枢轴值右面的 序列 重新快速排序 } } void print(int arr[], int n) { int i; for(i=0; i<n; i++) { printf("%d ",arr[i]); } printf("\n"); } int main() { int arr[]={9, 1, 5, 8, 3, 7, 4, 6, 2}; int n = sizeof(arr)/sizeof(arr[0]); printf("排序前:\n"); print(arr, n); QuickSort(arr,0,n-1); printf("排序后:\n"); print(arr, n); system("pause"); return 0; }
快速排序复杂度分析
最优情况:每次分割成两部分都很均匀,即两部分的数据相差不多。仅需递归logn次,算法时间复杂度为O(nlogn)
最坏情况:待排序为正序或反序,每次分割,都是一边为空,需要执行n-1次递归调用,且第i次划分需要经过n-i次的比较,因此比较次数为n-1+n-2+...+1=n(n-1)/2。其时间复杂度为O(n2)。
平均情况:
复杂度为O(nlogn);
快速排序是不稳定的排序。