经典排序算法之实现(五)
来源:互联网 发布:linux上的oracle启动 编辑:程序博客网 时间:2024/05/18 01:35
六、快速排序
1、基本思想
选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。
2、实例
例如关键字序列 ( 52, 49, 80, 36, 14, 75, 58, 97, 23, 61 )
经第1趟快速排序之后为 ( 23, 49, 14, 36) 52 (75, 58, 97, 80, 61 )
经第2趟快速排序之后为 ( 14) 23 (49, 36) 52 (61, 58) 75 (80, 97 )
经第3趟快速排序之后为 ( 14, 23, 36, 49, 52, 58, 61, 75, 80, 97 )
3、代码
/* *泡排序是通过一趟"起泡"选定关键字最大的记录,所有剩余关键字均小于它的记录继续进行排序, *快速排序则是通过一趟排序选定一个关键字介于"中间"的记录, *从而使剩余记录可以分成两个子序列分别继续排序,通常称该记录为"枢轴"。 *如右图所示,假设一趟快速排序之后枢轴记录的位置为 i, *则得到的无序记录子序列(1) R[s..i-1] 中记录的关键字均小于枢轴记录的关键字, *反之,得到的无序记录子序列(2)R[i+1..t] 中记录的关键字均大于枢轴记录的关键字, *由此这两个子序列可分别独立进行快速排序。 * *例如,关键字序列 ( 52, 49, 80, 36, 14, 75, 58, 97, 23, 61 ) *经第1趟快速排序之后为 ( 23, 49, 14, 36) 52 (75, 58, 97, 80, 61 ) *经第2趟快速排序之后为 ( 14) 23 (49, 36) 52 (61, 58) 75 (80, 97 ) *经第3趟快速排序之后为 ( 14, 23, 36, 49, 52, 58, 61, 75, 80, 97 ) * * *一趟快排也称"一次划分",即将待排序列 R[s..t]"划分"为两个子序列R[s..i-1] 和 R[i+1..t], *i 为一次划分之后的枢轴位置。可以取待排序列中任何一个记录作为枢轴,但为方便起见, *通常取序列中第一个记录 R[s] 为枢轴,以它的关键字作为划分的依据。 *划分可如下进行:设置两个指针 low 和 high,分别指向待排序列的低端 s 和高端 t。 *若 R[high].key<R[s].key,则将它移动至枢轴记录之前; *反之,若 R[low].key>R[s].key,则将它移动至枢轴记录之后,并为避免枢轴来回移动, *可先将枢轴 R[s] 暂存在数组的闲置分量 R[0] 中。 * * * *注意:R[0]为数组的闲置分量 * */#include <iostream>using namespace std;int Partition( int *R, int low, int high){ // 对记录子序列 R[low..high] 进行一趟快速排序,并返回枢轴记录 // 所在位置,使得在它之前的记录的关键字均不大于它的关键字, // 而在它之后的记录的关键字均不小于它的关键字 R[0] = R[low]; // 将枢轴记录移至数组的闲置分量 int pivotkey = R[low]; // 枢轴记录关键字 cout << endl << "pivotkey : " << pivotkey << endl; while(low < high){ // 从表的两端交替地向中间扫描 while( low<high && R[high]>=pivotkey ){ --high; } if(low < high){//需要进行这样的判断,如果是由于low>=high而退出的循环,不需要移动数据 R[low++] = R[high]; // 将比枢轴记录小的记录移到低端 //cout << "移动的hign数据:" << R[high] << endl; } while (low<high && R[low]<=pivotkey ) ++low; if(low < high){ R[high--] = R[low]; // 将比枢轴记录大的记录移到高端 //cout << "移动的low数据:" << R[low] << endl; } } // while R[low] = R[0]; // 枢轴记录移到正确位置 //cout << "返回的pivotkey: " << low << endl; for(int i = 1; i<=10; i++){ cout << R[i-1] << " "; } return low; // 返回枢轴位置} void QSort(int *R, int s, int t ){ // 对记录序列 R[s..t] 进行快速排序 if (s < t){ // 长度大于1 int pivotloc = Partition(R, s, t);// 对 R[s..t] 进行一趟快排,并返回枢轴位置 QSort(R, s, pivotloc-1);//对低子序列递归进行排序 QSort(R, pivotloc+1, t);//对高子序列递归进行排序 }}int main(){ int li[10] = {0,38,65,97,76,13,27,48,55,4}; cout<<"注意:R[0]为数组的闲置分量"<<endl; for(int i = 1; i<=10; i++){ cout << li[i-1] << " "; } cout << endl; QSort(li,1,9); cout << endl; for(int i = 1; i<=10; i++){ cout << li[i-1] << " "; } cout << endl; return 0;}
- 经典排序算法之实现(五)
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- C++设计模式之二十一:Strategy(策略模式)
- 为什么++i可以作为左值,i++不能作为左值,针对int
- 在ubuntu11.10中修改桌面方格字体
- 面与卤的鹊桥相会——桥接模式
- Openfiler之二:Openfiler的配置
- 经典排序算法之实现(五)
- 个性化Vim -- 配置文件在哪里
- Component creation must be done on Event Dispatch Thread
- linux下的快捷键详细介绍
- Openfiler之一:Openfiler的安装
- phonics-4
- 腾讯微博开放平台开发吐槽
- IIS无法访问mp4的后缀
- 【linux视频教程】LVS+Keepalived搭建高可用的负载均衡集群系统