排序算法之快速排序的多种版本
来源:互联网 发布:网狐6603经典版源码 编辑:程序博客网 时间:2024/05/20 09:43
快速排序
快速排序相对于其他的排序算法是较为快速的一种排序算法,主要体现在它的时间复杂度上.它的主要思想是:先选取一个值做关键字,通过一趟排序将待排序的记录分割成独立的两部分,其中一部分记录均比关键字小,另一部分记录均比关键字大,则可分别对这两部分记录继续进行排序,以达到整个有序的目的.
因此快速排序中最重要的就是划分区间,在下文的实现中我将介绍三种类型的单趟排序.
一.左右指针法
先找到一个值做关键字(可以选择最后一个元素也可以选择第一个元素),在我的代码实现中我选取的是最后一个元素做关键字,从左边开始找比关键字大的元素,从右边开始找比关键字小的元素,将左右找到满足题意的值交换,当左右相遇时说明一趟排序已经结束,此时需要将相遇点与关键字交换.
int PastSortA(int *a,int start,int end){int left=start;int right=end;int ret=GetMid(a,start,end);swap(a[ret],a[end]);int pivotkey=a[end]; //最后一个做关键字while (left < right){//left找比pivotkey大的数//right找比pivotkey小的数while (left < right && a[left] <= pivotkey){++left;}while (left < right && a[right] >= pivotkey){--right;}if(left < right)swap(a[left],a[right]);}swap(a[right],a[end]);return right;}
二.挖坑法
挖坑法是左右指针法的一种变形,只不过是从左边找到比关键字大的元素时与关键字交换,从右边找到比关键字小的元素与关键字交换.
int PastSortB(int *a,int start,int end){int left=start;int right=end;int ret=GetMid(a,start,end);swap(a[ret],a[end]);int pivotkey=a[end];while (left < right){while (left < right && a[left] < pivotkey){++left;}swap(a[left],a[right]);while (left < right && a[right] > pivotkey){--right;}swap(a[right],a[left]);}a[left]=pivotkey;return left;}
三.前后指针法
开始时让prev指向start的前一个位置,cur指向start位置,从左向右,当cur找到指向的值小于关键字,将prev后移,如果cur和prev没有指向同一个位置,然后将prev所指向的值与cur所指向的值进行交换,最后交换prev和end指向的值.
int PastSortC(int *a,int start,int end){int ret=GetMid(a,start,end);swap(a[ret],a[end]);int pivotkey=a[end];int prev=start-1;int cur=start;while (cur < end){if (a[cur] < pivotkey && ++prev != cur){swap(a[prev],a[cur]);}++cur;}swap(a[++prev],a[end]);return prev;}
快速排序的优化
1).三数取中:在代码实现中GetMid()中就实现了在中间值,第一个值,最后一个值选取中间一个值,值得注意的是在这三个数选取中间值后将这个中间值放置到最后一个数的位置.
2).判断元素的个数:当数据较大时用快速排序,当数据较小时直接插入,一般这个值 为13.
int GetMid(int *a,int start,int end){int mid=start+((end-start)>>1);if (a[start] < a[end]){if(a[end] < a[mid])return end;else if(a[mid] > a[start])return mid;elsereturn start;}else //a[start] > a[end]{if(a[end] > a[mid])return end;else if(a[start] < a[mid])return start;elsereturn mid;}}
快速排序的递归&非递归
void QuickSort(int *a,int start,int end){if (start < end){int size=end-start+1;//数据较大快排if(size > 2){int div=PastSortB(a,start,end);QuickSort(a,start,div-1);QuickSort(a,div+1,end);}//数据较小直接插入else{InsertSort(a,size);}}}void QuickSortR(int *a,int start,int end){stack<int> s;s.push(end);s.push(start);while (!s.empty()){int left=s.top();s.pop();int right=s.top();s.pop();int div=PastSortC(a,left,right);if(left < div-1){s.push(div-1);s.push(left);}if(div+1 < right){s.push(right);s.push(div+1);}}}
- 排序算法之快速排序的多种版本
- 排序算法(五)快速排序多种版本
- 排序算法之快速排序的随机化版本
- 快速排序算法之所有版本的c/c++实现
- 快速排序算法之所有版本的c/c++实现
- 经典算法--快速排序的随机化版本
- python版本的快速排序算法
- 排序算法之快速排序
- 排序算法之快速排序
- 排序算法之快速排序
- 排序算法 之 快速排序
- 排序算法之快速排序
- 排序算法之快速排序
- 排序算法之快速排序
- 排序算法之快速排序
- 排序算法之快速排序
- 排序算法之快速排序
- 排序算法之快速排序
- 使用C汇编
- Error:ERROR ITMS-90474: "Invalid Bundle. iPad Multitasking support requires these orientations:
- 5亿投资A站和G站,中文在线欲借“二次元”之力敲开泛娱乐大门
- Selenium总结:模拟浏览器动态加载页面
- Spark底层通信RPC源码分析
- 排序算法之快速排序的多种版本
- strcpy实现
- 漫谈继承技术(六)
- 信息安全的再开始
- 位运算操作符详解二
- 杨辉三角
- Git常用命令
- 同样是购物狂欢,为什么“美黑五”被天猫“双十一”甩了10倍不止?
- 数据结构基础概念