首先简单谈下高速排序的特点,时间复杂度O(nLog n),最差时间复杂度O(n^2),平均时间O(nLog n).由于用到了函数栈,空间复杂度为O(lg n),最差为O(n).是一种不稳定的排序方法。基本思想是分治法,这位大大的http://blog.csdn.net/morewindows/article/details/6684558 讲的很清楚了,分治法+挖坑法,我就不多说了。就是以某个数为參照,使得左边的都小于他,右边的数都大于他。然后对他的左右两个区间採取相同的方法进行递归。

就其总体实现而言,有两大种思路,一是双边扫描,二是单边扫描。以下分别来上程序:

一、双边扫描

双边扫描是谭浩强书中的方法,个人认为比以下的单边扫描更好理解,也是博文里採用的方法。以下看程序:

void quickSort1(int* x, int l, int r){if(l < r){int i = l, j = r, key = x[l];while(i < j){while( i < j && x[j] >= key){j--;}if(i < j){x[i++] = x[j];}while(i < j && x[i] <= key){i++;}if(i < j){x[j--] = x[i];}}cout<<"i = " <<i<<" j = "<<j<<endl;x[i] = key;quickSort1(x, l, i-1);quickSort1(x, i+1, r);}}

双边扫描很直观,首先进到程序里推断是否l<r,当满足条件才进去。这也是用递归的一个必要条件,一定要让函数有尽头,有边界。然后进入大while循环,接着进入小while循环,先从右边找,仅仅要满足数字大于key就一直让j往左移。直到第一个不满足条件的,就是第一个小于key的数跳出while循环,将它放在左边挖的“坑”上。同一时候让坑的索引+1,接着从左边開始扫描,找到第一个大于key的数,再将它填到右边的坑上。右边的坑索引-1,接着再从右边扫描。直到最后跳出大while循环,此时i = j。也就是完毕了一次高速排序的扫描。之后将最初的key放到x[i],事实上放到x[j]也是一样的。由于i等于j么,此时!然后进行递归,对区间[l, i - 1], [i+1, r]进行相同的操作。

双边排序的要点: 1、最初的if一定要有,这是最后递归出来的标志位。2,为了找到一个数使它的左边都大于它,右边都小于它,要多次循环,这个循环就是大while循环。3、双边排序不须要swap,即无需交换。

二、单边扫描

上面的双边排序,出来一次大while循环,要从两边进行多次。单边扫描,则仅仅需从左走到右就能完毕一次 快排。

void quickSort2(int x[], int l, int r){if(l >= r)return;int m = l;for(int i = l + l; i <= r; i++ ){if(x[i] < x[l]){swap2(x[++m], x[i]);}}swap2(x[l], x[m]);quickSort2(x, l, m - 1);quickSort2(x, m + 1, r);}
void swap2(int &a,int &b){if(a==b) return;//对同一地址的数据交换,会使其结果为0a=a^b;b=a^b;a=a^b;
}

代码是不是更简单了?程序先进行推断,假设l>=r直接return,这点跟双边扫描的if一个意思,都是为递归创造结束的标志。然后用m记录最左边的那个的索引,这里默认的是第一个,即x[l]的索引。[注,m的初始值不一定指向key!,仅仅是指向最左边的。]然后进入扫描,直接从l + 1開始,假设右边的小于key,就让x[++m]和x[i]交换。假设右边的大于key,则不进行不论什么操作。这里有个特例,假设l = 0, 则m = 0.假设x[1]小于x[0],则让x[1] 和x[1]进行交换,也就等于没交换。假设数组是5 4 3 2 1,则这里的交换就失效了。 再往后看,直到for循环结束,走出循环,让最后m指的位置的数和最初的key进行交换。如上面 5 4 3 2 1,则第一次快排的结果是 1 4 3 2 5,仅仅有for出来后的那次swap才起作用。这里的m有个特殊含义,即指向小于key的最右边的那个数。所以出来后才用它(x[m])和key(即x[l])进行交换。

单边扫描的特点:

1、程序须要交换;

2、更有冒泡法的色彩;冒泡的目的不是让最大的数沉到最右边,而是让小于key的都左移,找到分界索引m。使之和key进行交换。

3、此版本号的的单边扫描属于最基础的,还能够优化。

本想測出两个算法的时间 消耗差异,遗憾的是c++获得程序执行时间太费劲了,弄半天没弄成。以下附上完整程序:

//============================================================================
// Name        : QuikSort.cpp
// Author      : YanZi
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================#include <iostream>
#include <malloc.h>using namespace std;
void swap1(int a, int b);
void printArray(int* in, int n);void quickSort1(int* x, int l, int r);//双边扫描,高速排序
void quickSort2(int x[], int l, int r);//单边扫描,高速排序
void swap2(int &a,int &b); //交换,在MinGW上必须採用此方法,swap1无效#define N 8 //数组的长度int main() {int* input = NULL;input = (int*)malloc(N * sizeof(int));if(input == NULL){cout<<"内存溢出"<<endl;}for(int i = 0; i < N; i++){input[i] = rand();}//  int input[] = {55, 41, 59, 26, 53, 58, 97, 93};cout<<"原始数据:"<<endl;printArray(input, N);quickSort2(input, 0, N-1);printArray(input, N);return 0;
}
void swap1(int a, int b){int temp = a;a = b;b = temp;
}
void printArray(int * in, int n){if(in == NULL){return;}for(int i = 0; i<n; i++){cout<<" "<<in[i];}cout<<endl;}void quickSort1(int* x, int l, int r){if(l < r){int i = l, j = r, key = x[l];while(i < j){while( i < j && x[j] >= key){j--;}if(i < j){x[i++] = x[j];}while(i < j && x[i] <= key){i++;}if(i < j){x[j--] = x[i];}}cout<<"i = " <<i<<" j = "<<j<<endl;x[i] = key;quickSort1(x, l, i-1);quickSort1(x, i+1, r);}}
void quickSort2(int x[], int l, int r){if(l >= r)return;int m = l;for(int i = l + l; i <= r; i++ ){if(x[i] < x[l]){swap2(x[++m], x[i]);}}swap2(x[l], x[m]);quickSort2(x, l, m - 1);quickSort2(x, m + 1, r);}
void swap2(int &a,int &b){if(a==b) return;//对同一地址的数据交换,会使其结果为0a=a^b;b=a^b;a=a^b;
}

算法整理(二)---高速排序的两种实现方式:双边扫描和单边扫描相关推荐

  1. 算法整理(二)---快速排序的两种实现方式:双边扫描和单边扫描

    首先简单谈下快速排序的特点,时间复杂度O(nLog n),最差时间复杂度O(n^2),平均时间O(nLog n).因为用到了函数栈,空间复杂度为O(lg n),最差为O(n).是一种不稳定的排序方法. ...

  2. c++层次遍历_数据结构与算法,弄懂图的两种遍历方式

    1 引言   遍历是指从某个节点出发,按照一定的的搜索路线,依次访问对数据结构中的全部节点,且每个节点仅访问一次.  在二叉树基础中,介绍了对于树的遍历.树的遍历是指从根节点出发,按照一定的访问规则, ...

  3. jqGrid排序的两种实现方式

    实现方案一客户端实现排序: jqGrid属性 loadonce:true时,所有数据加载在客户端,点击列标题由jqGrid在客户端自动排序,不再从服务器取值. 参考文件:ccMxCxTjCc.js j ...

  4. (转)javabean是什么和总结javabean的两种使用方式

    一. javabean 是什么? Javabean 就是一个类,这个类就定义一系列 get<Name> 和 set<Name> 方法. So simple ! Javabean ...

  5. JavaBean是什么和总结JavaBean的两种使用方式

    转载于:http://www.blogjava.net/flysky19/articles/88180.html 一. javabean 是什么? Javabean 就是一个类,这个类就定义一系列 g ...

  6. 拓扑排序的两种实现:Kahn算法和dfs算法

    本文将从以下几个方面介绍拓扑排序: 拓扑排序的定义和前置条件 和离散数学中偏序/全序概念的联系 典型实现算法 Kahn算法 基于DFS的算法 解的唯一性问题 实际例子 取材自以下材料: http:// ...

  7. 二分查找算法的两种实现方式:非递归实现和递归实现

    二分查找的条件是对一组有序数组的查找,这一点很容易忘记,在使用二分查找的时候先要对数组进行排序. 先说一下二分查找的思路:一个有序数组,想要查找一个数字key的下标,首先算出中间下标mid,利用mid ...

  8. a - 数据结构实验之串一:kmp简单应用_串的两种模式匹配方式(BF/KMP算法)

    串的两种模式匹配方式(BF/KMP算法) 前言 串,又称作字符串,它是由0个或者多个字符所组成的有限序列,串同样可以采用顺序存储和链式存储两种方式进行存储,在主串中查找定位子串问题(模式匹配)是串中最 ...

  9. php order by 3-- 没反应,Thinkphp 无法使用-)order() 排序的两种解决办法!

    Thinkphp 无法使用-)order() 排序的两种解决办法! 使用ThinkPHP,站群,却发现无法使用->order($order)来排序. $order = " info.d ...

  10. 计算机word降序排列怎么做,word中怎么进行排序的两种方法

    word文档中表格除了作为我们的编辑和展示功能之外,还可以进行排序功能,十分方便,那么下面就由学习啦小编给大家分享下word中进行排序的技巧,希望能帮助到您. word中进行排序方法一: 步骤一:将光 ...

最新文章

  1. teamviewer设备数量上限_智能控制设备连接故障排除
  2. r语言 java mysql_R语言 可不可以取代数据库?
  3. 解决 Oralce 执行set autotrace on时的SP2-0618和SP2-0611错误
  4. 集成电路883和883b有什么区别
  5. tail实时监控日志qps
  6. why is pricing callback CRM_PRIDOC_UPDATE_EC called
  7. android横竖屏切换布局闪退,Android-Activity横竖屏切换不杀死Activity 并监听横竖屏切换...
  8. matlab cell向量匹配向量,根据2个cell格式数据中的某二列进行匹配并合并
  9. 站立会议中发现的一些新问题
  10. SAP License:统计型实际结算型内部订单
  11. 记录一次nginx 配置https 强制http转发到https
  12. MongoDB最简单的入门教程之二 使用nodejs访问MongoDB 1
  13. jq跨域代理_JQuery前端跨域问题的七种解决方案
  14. 10款平面设计软件锦集,“学废”一样都可独挡一面!
  15. 寒江独钓-Windows内核安全编程(完整版).pdf
  16. 微信应用号(小程序)开发IDE配置
  17. 读书 | 颠覆者:周鸿祎自传
  18. 今日小程序推荐:汇率即时查-打通微信直接搜一搜
  19. Day 07 类、魔方方法
  20. postgresql点云las_基于PostgreSQL数据库的大数据点云存储技术应用研究

热门文章

  1. 编程之美读书笔记1.3 —— 一摞烙饼的排序
  2. 网页开发者模式调整到手机模式_苹果全球开发者大会将于6月22日召开 全线上模式...
  3. java 象限分析_用四种象限分析你(未来的人生走向)
  4. 力扣-830 较大分组的位置
  5. 迅为IMX6Q PLUS开发板烧写Android6.0系统方法
  6. CentOS 6 忘记root密码的修改方法
  7. 黑匣子_NOI导刊2010提高 (对顶堆)
  8. 2 创建型模式之 - 工厂模式
  9. (一)apache atlas源代码编译与打包
  10. 太赞了!超炫的页面切换动画效果【附源码下载】