赞
踩
快速排序是排序中的最佳实用选择,虽然在最坏情况下的时间复杂度为O(n^2), 但在随机输入的情况下,其时间复杂度为O(nlogn).
一、快速排序也是基于分治策略,其三个步骤为:
分解:将待排序数组A[p,r]分解为A[p,q]和A[q+1,r]两个数组,使得A[p,q]中的每个元素都小于A[q+1,r]中的每个元素。q值在分解中计算得到。
解决:通过递归调用对两个子数组A[p,q]和A[q+1,r]进行排序。
合并:无需合并,A[p,r]为已经排好的数组。
二、举个例子(想吃栗子了)
一个有7个待排元素的数组
1.让pivot = a[0]=5, 称为哨兵。通常取第一个元素。z,y为两个指针,分别从前、后扫描数组
2.进入循环,a[y] = a[6]<5,y不动;满足z<y,则a[z] = a[0] =a[y] = 4,z++;
3.a[z] = a[1] = 2<5,z++;a[z] = 6>5;满足z<y,则a[y] = a[6] =a[z] = 6,y--;
4.a[y]<5,y不动;满足z<y;a[z] = a[y] = 3;z++;
5.a[z]<5,z++;a[z]>5;满足z<y;a[y] = a[z] = 7;y--;
6.z=y,退出循环,a[z] = a[y] = pivot = 5;结束;呼
之后调用递归,对a[0]-a[3],a[5]-a[6]进行划分。
代码如下
- #include<iostream>
- using namespace std;
-
- void quickSort(int *src, int low,int high)
- {
- if(src == NULL) return ;
- int i,j,pivot;
- if(low < high)
- {
- pivot = src[low];
- i = low,j = high;
- while(i < j)
- {
- while(i<j && src[j] >= pivot) j--;
- src[i] = src[j];
-
- while(i<j && src[i] <= pivot) i++;
- src[j] = src[i];
- }
-
- src[i] = pivot;
-
- quickSort(src,low,i-1);
- quickSort(src,i+1,high);
- }
- }
-
- int main()
- {
- int src[] = {49,38,65,97,76,13,27,49};
-
- int i,low,high,cnt = sizeof(src)/4;
-
- quickSort(src,0,cnt-1);
-
- //输出
- for(i = 0; i < cnt; i ++) cout<<src[i]<<" ";
- cout<<endl;
-
- getchar();
- return 0;
- }
三、性能分析
1.最坏情况:每一次划分都是极不对称的,假设每次划分两个区域分别保护1个和n-1个元素(例如,原数组是以排好序的)。划分的时间代价为O(n),则
算法运行时间为T(n) = T(n-1)+O(n)
2.最佳情况:对称划分,划分过程中产生的两个区域都包含n/2元素。
算法的运行时间T(n) = 2T(n/2)+O(n), 则T(n) = O(nlogn);
3.平均情况:快排的平均情况与最佳情况很接近,T(n) = O(nlogn);(证明可参看《算法导论》8.4,,其实记住就好了嘛)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。