排序算法学习经验(四)
来源:互联网 发布:刷手淘宝号 编辑:程序博客网 时间:2024/06/05 13:29
上次提到了快速排序并的基本实现方法,并简单分析了导致快速排序极度不平衡的情况发生的原因,针对这个原因,双路快排或许能够减少这种不平衡发生的次数。
双路快排
双路快排的原理是在快速排序的基础上,使标定点两边,关键码等于标定点的元素分布平衡,而不是全部分布在左半部分。
具体实现思路如下:
1.选定标定点同快速排序,用swap(arr[l], arr[rand() % ( r - l + 1) +l)]),然后标定点为arr[l]。
2.首先定义i为最后一个小于等于标定点的关键码的下标,j为第一个大于等于标定点的关键码的下标。
3.然后从标定点的下一个元素开始(即arr[l + 1]开始),向后扫描,如果arr[i]小于标定点的关键码,则继续向后扫描,直到arr[i]大于或者等于标定点的关键码后停止。
同理,从数组的最后一个元素开始(即arr[r]开始),向前扫描,如果arr[j]大于标定点的关键码,则继续向前扫描,直到arr[j]小于或等于标定点的关键码后停止。
4.此时,i下标对应的元素和j下标对应的元素进行交换(这一步就将快速排序的不平衡优化了),使与标定点相等关键码的元素比较均匀地分布在两边。
5.当i>j时,循环结束。
6.partition完成
下面看看C++代码实现:
#pragma once#include<iostream>using namespace std;//对小规模数组,使用插入排序优化template<typename T>void insertionSort3(T arr[], int l, int r){ for (int i = l + 1; i <= r; i++) { T e = arr[i]; int j; for (j = i; arr[j - 1] > e && j > l; j--) { arr[j] = arr[j - 1]; } arr[j] = e; }}template<typename T>int partition2(T arr[], int l, int r){ //选定标定点 swap(arr[l], arr[rand() % (r - l + 1) + l]); T e = arr[l]; int i = l + 1;//最后一个小于等于标定点关键码的元素下标 int j = r;//第一个大于等于标定点关键码的元素下标 while (true) { //向后扫描,到arr[i]>=e时停止 while (i <= r && arr[i] < e) { i++; } //向前扫描,到arr[i]<=e时停止 while (j >= l + 1 &&arr[j] > e) { j--; } if (i > j) break; //平衡操作 swap(arr[i], arr[j]); i++; j--; } swap(arr[l], arr[j]); return j;}template<typename T>void __quickSort2Ways(T arr[], int l, int r){ //递归到底的情况,和前面类似用插入排序 if (r - l <= 9) { insertionSort3(arr, l, r); return; } int p = partition2(arr, l, r);//标定点 //递归到底层后数组就成为有序的数组 __quickSort2Ways(arr, l, p - 1);//左层递归调用,继续partition __quickSort2Ways(arr, p + 1, r);//右层递归调用,继续partition}template<typename T>void quickSort2Ways(T arr[], int n){ srand(unsigned(time(NULL))); //设置随机种子 __quickSort2Ways(arr, 0, n - 1); //初次调用}
阅读全文
0 0
- 排序算法学习经验(四)
- 排序算法学习经验(一)
- 排序算法学习经验(二)
- 排序算法学习经验(三)
- 算法学习之排序算法(四)(希尔排序)
- 算法学习(四)冒泡排序
- 算法学习(四)----快速排序
- 四种排序算法学习
- 排序算法(四)快速排序算法
- 算法学习(四)——归并排序
- 算法学习(排序四)最大子数组问题
- 算法学习之四:桶排序
- 排序算法总结(四)
- Java排序算法(四):冒泡排序
- 排序算法(四):冒泡排序
- Java排序算法(四):冒泡排序
- 排序算法总结(四)希尔排序
- 排序算法(四):快速排序
- Android OpenGL教程-第二课【转】
- 4.从Request中获取文件数据
- 结构体变量的引用
- 日常记录
- MyBatis注解方式与映射文件方式配合实现一对一,一对多,多对多(一)
- 排序算法学习经验(四)
- 【DFS】UVa839 天平(Not so Mobile)
- 图片剪裁批处理
- Spring boot介绍(一)
- 5.API中的文件上传与接收
- 莫名其妙CSDN不让我发帖子了。看来10年的老水手我该离开CSDN了。
- 6.JavaMail发送邮件
- 程序员不愿意加班的真相......
- 用Sublime Text运行C++代码