快速排序测试(QuickSort)
来源:互联网 发布:simulink数据库 编辑:程序博客网 时间:2024/06/02 13:49
一. 目的
进行快速排序练习,掌握快速排序的原理。
算法证明:
第一步,数组分为四个区,无序小于关键值区A[1]-A[i],无序大于关键值区A[i+1]-A[j],待划分区A[j+1]-A[N-1],关键值区A[N],第一步时,只有两个区域不为空,即带划分区A[1]-A[N-1],关键值区A[N]
第二步:进入循环处理,若存在可以放在无序小区的元素,则将无序大区则将无序大区的下界元素与A[j]交换,此时无序小区的上界增长一。到循环结束序列存在三个不为空区,A[1]-A[i],A[i+1]-A[N-1],将A[i+1]与A[N]交换,此时关键值已经放在合适位置,前面的元素小于关键值,后面的元素大于关键值。
第三步:对前后两个区域进行相同划分,最终每个元素都处在自己的合适位置,算法证明完毕。
二. 实现代码
1、单向划分
//快速排序标准算法 void QuickSort(T testArray[], int nSize){ LogInfo<T> log = LogInfo<T>(); log.ShowState("原始数组为:"); log.ShowArray(testArray, nSize); QuickSortSub(testArray, 0, nSize - 1); log.ShowState("最终数组为:"); log.ShowArray(testArray, nSize); } void QuickSortSub(T testArray[], int Begin, int End){ if (Begin < End){ //获取中轴位置,该位置元素以及在位,且区分了两个部分,前面为小值区,后面为大值区 int pivot = QuickSortPartition(testArray, Begin, End); //对两个区域进行快速排序 QuickSortSub(testArray, Begin, pivot - 1); QuickSortSub(testArray, pivot + 1, End); } } //快速排序的划分,返回划分位置,划分位置的元素已经在该在的位置 int QuickSortPartition(T testArray[], int Begin, int End){ //单个元素或者没有元素则退出 if (Begin >= End) return 0; T key = testArray[End]; T tmp(0); //i记录已经放小于哨兵的元素位置 int i = Begin - 1; for (int j = Begin; j < End; j++){ //若J元素小于少哨兵值,则将i+1与j交换。 if (testArray[j] < key){ i++; tmp = testArray[i]; testArray[i] = testArray[j]; testArray[j] = tmp; } } testArray[End] = testArray[i + 1]; testArray[i + 1] = key; return i + 1; }
2、双向遍历,将大元素放在后端,小元素放在前端
//快速排序双向遍历算法 void QuickSortVerTwoDirection(T testArray[], int nSize){ LogInfo<T> log = LogInfo<T>(); log.ShowState("原始数组为:"); log.ShowArray(testArray, nSize); QuickSortSubVerTwoDirection(testArray, 0, nSize - 1); log.ShowState("最终数组为:"); log.ShowArray(testArray, nSize); } //双向遍历快速排序 void QuickSortSubVerTwoDirection(T testArray[],int Begin,int End){ if (Begin < End){ //获取划分点 int pivot = QuickSortPartitionTwoDirection(testArray, Begin, End); QuickSortSubVerTwoDirection(testArray, Begin, pivot - 1); QuickSortSubVerTwoDirection(testArray, pivot + 1, End); } } //快速排序双向交换法 int QuickSortPartitionTwoDirection(T testArray[], int Begin, int End){ T key = testArray[Begin];//记录划分值 T tmp(0); while (Begin < End){ //从尾部寻找小于划分值的位置,将该元素放在头部 while (Begin<End && testArray[End]>key)End--; tmp = testArray[End]; testArray[End] = testArray[Begin]; testArray[Begin] = tmp; //从头部寻找大于划分元素的位置,将该元素放在尾部 while (Begin < End && testArray[Begin] <= key)Begin++; tmp = testArray[End]; testArray[End] = testArray[Begin]; testArray[Begin] = tmp; } return Begin; }
3、随机快速排序
//随机化快速排序 void QuickSortVerRandom(T testArray[], int nSize){ LogInfo<T> log = LogInfo<T>(); log.ShowState("原始数组为:"); log.ShowArray(testArray, nSize); QuickSortSubVerRandom(testArray, 0, nSize - 1); log.ShowState("最终数组为:"); log.ShowArray(testArray, nSize); } //随机版本快速排序 void QuickSortSubVerRandom(T testArray[], int Begin, int End){ if (Begin < End){ //产生随机下标与关键值(结尾元素)交换 int Index = RandomKeyIndex(Begin, End); if (Index != End){ T tmp = testArray[End]; testArray[End] = testArray[Index]; testArray[Index] = tmp; } //获取划分点 int pivot = QuickSortPartitionTwoDirection(testArray, Begin, End); QuickSortSubVerRandom(testArray, Begin, pivot - 1); QuickSortSubVerRandom(testArray, pivot + 1, End); } } //随机版本快速排序划分 int QuickSortPartitionRandom(T testArray[], int Begin, int End){ T key = testArray[End]; T tmp(0); //i记录已经放小于哨兵的元素位置 int i = Begin - 1; for (int j = Begin; j < End; j++){ //若J元素小于少哨兵值,则将i+1与j交换。 if (testArray[j] < key){ i++; tmp = testArray[i]; testArray[i] = testArray[j]; testArray[j] = tmp; } } testArray[End] = testArray[i + 1]; testArray[i + 1] = key; return i + 1; } //产生一个数据在Begin与End之间 int RandomKeyIndex(int Begin, int End){ srand((unsigned int)time(NULL));//产生一个随机种子。 int Index = rand() % (End - Begin + 1) + Begin; return Index; }
输出结果
三. 遇到难题
1、初次看到标准快速算法,由于太多变量,导致看起来很费力。
2、对于双向快速排序,只需要划分三个区,没有四个区,用四区划分来看着这个算法有些困难。
四. 经验总结
1、快速排序适用和要求序列相同的序列,就会发生退化,退化为冒泡排序,复杂度O(N^2)
2、随机化快速排序不再将指定特定元素作为关键值。产生更好的效果,对待已经有序的序列不再那么糟糕。
3、快速排序主要影响因素是划分的平衡性。
4、快速排序的平均复杂度为O(nlog(n)),算法不稳地。
五. 后续处理
今天要写另外两篇日记,完成排序算法这一块,然后来一个总结。
六. 参考文献
1、算法导论
2、 八大排序算法 http://blog.csdn.net/abcbig/article/details/42774333
- 快速排序测试(QuickSort)
- 快速排序(quickSort)
- 快速排序(Quicksort)
- 快速排序(QuickSort)
- 快速排序(Quicksort)
- 快速排序(Quicksort)
- 快速排序(Quicksort)
- 快速排序(Quicksort)
- 快速排序(QuickSort)
- 快速排序(Quicksort)
- 快速排序(QuickSort)
- 快速排序(Quicksort)
- 快速排序(Quicksort)
- 快速排序(QuickSort)
- 快速排序(Quicksort)
- 快速排序(QuickSort)
- 快速排序(QuickSort)
- 再看快速排序(QuickSort)
- 排序算法的稳定性
- Ubuntu安装PhpStorm
- zencart export批量导出数据,生成csv操作
- 11.层级导航
- <div+css页面布局课堂笔记>10---页面布局网站首页设计实例__2
- 快速排序测试(QuickSort)
- Android新手入门2016(16)--画图
- 搭车系统 use端
- 设计模式C C++
- MyBatis中关于一对多情况
- 学习java的一些感言!
- IDEA -- IntelliJ IDEA14 创建JavaWeb工程 配置Tomcat 部署 运行
- QImage Mat QPixmap转换
- android PullToRrefresh自定义下拉刷新动画