算法系列—快速排序及其优化(递归)
来源:互联网 发布:java做贪吃蛇游戏 编辑:程序博客网 时间:2024/04/30 09:49
快速排序和归并排序是互补的,归并排序将子数组分成两个子数组分别排序,并将有序的子数组归并以将整个数组排序。而快速排序则是当两个子数组有序时整个数组也就自然有序了。
归并排序:递归调用发生在整个数组处理之前,一个数组被等分为两半。
快速排序:递归调用发生在处理整个数组之后,切分的位置取决于数组的内容。
初步实现如下:
#include <iostream>#include <algorithm>void sort(int A[], int lo, int hi);int partition(int A[], int lo, int hi);void QuickSort(int A[], int size){std::random_shuffle(A, A + size - 1);//打乱数组sort(A, 0, size - 1);}void sort(int A[],int lo,int hi){if (lo >= hi)return;int j=partition(A, lo, hi);sort(A, lo, j - 1);sort(A, j + 1, hi);}int partition(int A[],int lo,int hi){//将数组切分为A[lo...i-1],A[i],A[i+1...hi]int i = lo, j = hi + 1; //扫描指针int a = A[lo];//切分元素while(true){while (A[++i] < a);//左侧元素小于切分元素则继续比较下一个while (A[--j] > a);//右侧元素大于切分元素则比较下一个if (i > j)//当两个指针相遇break;std::swap(A[i], A[j]);}std::swap(A[lo], A[j]);//扫描指针相遇后将切分元素放入正确位置return j;}int main(){int A[] = { 1,4,6,4,7,4,10,50,88,2,33,56,3,345,66,67,4 };QuickSort(A, sizeof(A) / 4);for (auto a : A){std::cout << a << " ";}}
random_shuffle()打乱数组的目的:快速排序在切分不平衡时程序可能会极为低效,比如第一次从第一小的元素开始切分,第二次从第二小的元素开始切分。。在快速排序前将数组打乱就是为了避免这种情况。
算法改进:
(1)对于小数组,快速排序比插入排序慢,因此排序小数组时切换到插入排序
将sort中的语句if(hi<=lo) return;
改为
if(hi<=lo+M)
{
//插入排序
return;
}
(2)三取样切分
实际应用中常会出现大量重复元素的数组,一个简单的方法是将数组切分为三部分,分别小于,等于和大于切分元素。
思路:从左到右遍历数组一次,维护一个指针lt使得A[lo...lt-1]中的元素都小于切分元素。一个指针gt,使得A[gt+1...hi]中的元素都大于切分元素。一个指针i使得A[lt...i-1]中的元素都等于切分元素,A[i...gt]中的元素还不确定。
比较时:
A[i]小于切分元素,将A[lt]和A[i]交换,lt和i加一
A[i]大于切分元素,将A[gt]和A[i]交换,gt减一
A[i]等于切分元素,将i加一.。
三取样切分的快速排序如下:
#include <iostream>#include <algorithm>void sort(int A[], int lo, int hi);void QuickSort(int A[], int size){std::random_shuffle(A, A + size - 1);//打乱数组sort(A, 0, size - 1);}void sort(int A[], int lo, int hi){if (lo >= hi) //如果越界return;int lt = lo, i = lo + 1, gt = hi;int v = A[lo];//切分元素while (i <= gt){if (A[i] < v)std::swap(A[i++], A[lt++]);else if (A[i] == v)i++;else {std::swap(A[i], A[gt--]);}}//sort(A, lo, lt - 1);sort(A, gt + 1, hi);}int main(){int A[] = { 1,4,6,4,7,4,10,50,88,2,33,56,3,345,66,67,4 };QuickSort(A, sizeof(A) / 4);for (auto a : A){std::cout << a << " ";}}
0 0
- 算法系列—快速排序及其优化(递归)
- 快速排序算法及其优化
- 快速排序算法及其优化
- 快速排序算法及其优化方法
- 快速排序算法实施尾递归优化
- 快速排序(递归算法)
- 快速排序算法(递归)
- 排序(6)——快速排序及其优化
- 快速排序及其优化
- 快速排序及其优化
- 快速排序及其优化
- 快速排序及其优化
- 快速排序及其优化
- 快速排序及其优化
- 快速排序及其优化
- 快速排序及其优化
- 快速排序及其优化
- 快速排序及其优化
- C++设计模式(一)装饰者
- 1-1 欢迎来的C++世界
- Web前端性能优化之CDN加速
- jquery validate (jquery 验证的三种方式)
- Linux学习---搜索命令
- 算法系列—快速排序及其优化(递归)
- js gbk与UTF8 转换
- Web前端性能优化之反向代理
- *[Lintcode]Longest Increasing Subsequence 最长上升子序列
- Android JNI/NDK开发之基本姿势<一>
- Ubuntu上C++高精度时间的测量
- 1-2 输出N个数的平方和立方值
- sql 获取字符串长度SQL字符串操作汇总
- SpringMVC<from:form>表单标签和<input>表单标签简介