这里不详细说明快速排序的原理,具体可参考here

快速排序主要是partition的过程,partition最常用有以下两种写法

第一种:

  1. int mypartition(vector<int>&arr, int low, int high)
  2. {
  3. int pivot = arr[low];//选第一个元素作为枢纽元
  4. while(low < high)
  5. {
  6. while(low < high && arr[high] >= pivot)high--;
  7. arr[low] = arr[high];//从后面开始找到第一个小于pivot的元素,放到low位置
  8. while(low < high && arr[low] <= pivot)low++;
  9. arr[high] = arr[low];//从前面开始找到第一个大于pivot的元素,放到high位置
  10. }
  11. arr[low] = pivot;//最后枢纽元放到low的位置
  12. return low;
  13. }

第二种:

  1. int mypartition(vector<int>&arr, int low, int high)
  2. {
  3. int pivot = arr[high];//选最后一个元素作为枢纽元
  4. int location = low-1;//location指向比pivot小的元素段的尾部
  5. for(int i = low; i < high; i++)//比枢纽元小的元素依次放在前半部分
  6. if(arr[i] < pivot)
  7. swap(arr[i], arr[++location]);
  8. swap(arr[high], arr[location+1]);
  9. return location+1;
  10. }

当第二种方法也可以选择第一个元素作为枢纽(当我们对链表进行快排时选用这种做法),对上面代码稍作改动即可,具体改动见注释                         本文地址

  1. int mypartition(vector<int>&arr, int low, int high)
  2. {
  3. int pivot = arr[low];//选第一个元素作为枢纽元
  4. int location = low;//location指向比pivot小的元素段的尾部
  5. for(int i = low+1; i <= high; i++)//比枢纽元小的元素依次放在前半部分
  6. if(arr[i] < pivot)
  7. swap(arr[i], arr[++location]);
  8. swap(arr[low], arr[location]);//注意和前面的区别,是为了保证交换到头部的元素比pivot小
  9. return location;
  10.  
  11. }

快排主函数如下:

  1. void quicksort(vector<int>&arr, int low, int high)
  2. {
  3. if(low < high)
  4. {
  5. int middle = mypartition(arr, low, high);
  6. quicksort(arr, low, middle-1);
  7. quicksort(arr, middle+1, high);
  8. }
  9. }

快排非递归实现

主要思想是用栈来保存子数组的左右边界,一下代码中用数组模拟栈

  1. void quicksort_unrecursion(vector<int>&arr)//快速排序非递归
  2. {
  3. int mystack[2000];//假设递归不超过1000层
  4. //栈中保存下次需要排序的子数组的开始位置和结束位置
  5. int top = -1;
  6. mystack[++top] = 0;
  7. mystack[++top] = arr.size() - 1;
  8. while(top > 0)//栈非空
  9. {
  10. int high = mystack[top--], low = mystack[top--];
  11. int middle = mypartition(arr, low, high);
  12. if(middle+1 < high)//右边子数组入栈
  13. {
  14. mystack[++top] = middle+1;
  15. mystack[++top] = high;
  16. }
  17. if(low < middle-1)//左边子数组入栈
  18. {
  19. mystack[++top] = low;
  20. mystack[++top] = middle-1;
  21. }
  22. }
  23. }

【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3665038.html

快速排序partition过程常见的两种写法+快速排序非递归实现的更多相关文章

  1. 用Python计算幂的两种方法,非递归和递归法

    用Python计算幂的两种方法: #coding:utf-8 #计算幂的两种方法.py #1.常规方法利用函数 #不使用递归计算幂的方法 """ def power(x, ...

  2. ORACLE 查询一个数据表后通过遍历再插入另一个表中的两种写法

    ORACLE 查询一个数据表后通过遍历再插入另一个表中的两种写法 语法 第一种: 通过使用Oracle语句块  --指定文档所有部门都能查看 declare cursor TABLE_DEPT and ...

  3. EF架构~linq模拟left join的两种写法,性能差之千里!

    回到目录 对于SQL左外连接我想没什么可说的,left join将左表数据都获出来,右表数据如果在左表中不存在,结果为NULL,而对于LINQ来说,要实现left join的效果,也是可以的,在进行j ...

  4. Java 获取*.properties配置文件中的内容 ,常见的两种方法

    import java.io.InputStream; import java.util.Enumeration; import java.util.List; import java.util.Pr ...

  5. 运算符关键字。数据区别大小写。日期范围。判空的两种写法。NOT IN的两种写法。IN范围可含NULL,但NOT IN值范围不能含NULL。

    比较:>,<,=,>=,<=,<>(!=) 逻辑:AND,OR,NOT 范围:BETWEEN...AND... 范围:IN,NOT IN 判空:IS NULL, I ...

  6. java 路径分隔符File.separator 以及 路径两种写法"/"和"\\"

    一.File.separator File file=new File(); 这句是新建一个文件.file.separator这个代表系统目录中的间隔符,说白了就是斜线,不过有时候需要双线,有时候是单 ...

  7. iOS中表视图单元格事件用nib和storyboard的两种写法总结

    从ios6开始,苹果公司推出了storyborad技术取代了nib的写法,这样代码量确实少写了很多,也比较简洁.但是,从学习的角度来说,阿堂认为 用nib的写法,虽然多了些代码,但是对于掌握知识和原理 ...

  8. linq和ef关于group by取最大值的两种写法

    LINQ: var temp = from p in db.jj_Credentials group p by p.ProfessionID into g select new { g.Key, Ma ...

  9. ThinkPHP中Widget的两种写法及调用

    Widget扩展一般用于页面组件的扩展,在页面根据需要输出不同的内容,下面介绍一下ThinkPHP中Widget的两种写法及调用 写法一: ArticlWidget.class.php文件: clas ...

随机推荐

  1. 认识js运动

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. 搬家通知博文地址(将博客搬到CSDN)

    (为了确认是您本人在申请搬家,请在原博客发表一 篇标题为<将博客搬至CSDN>的文章,并将文章地址填写在上方的"搬家通知博文地址"中.)

  3. 配置apache和php mysql的一些问题

    关于"Windows不能在本地计算机启动Apache2.......并参考特定服务错误代码1"问题解决 apache的httpd.conf文件配置“LoadModule php5_ ...

  4. 050 sqoop的使用

    一:导入  mysql-->hdfs 1.准备 2.导入数据 可以看到在跑yarn. 3.在HDFS上看结果 默认的地址:hdfs的家目录. 4.在HDFS上指定目录 5.指定map的个数,相同 ...

  5. 第一次亲密接触MSF

    第一次亲密接触MSF Metasploit Framework介绍 Metasploit是一款开源安全漏洞检测工具,附带数百个已知的软件漏洞,并保持频繁更新.被安全社区冠以“可以黑掉整个宇宙”之名的强 ...

  6. js类型判断-丰富加好用

    一, 自己有时候写一些东西,要做类型判断,还有测试的时候,对于原生的和jQuery中的类型判断,实在不敢恭维,所以就写了一个好用的类型判断,一般情况都够用的. function test(type) ...

  7. luoguP4709 信息传递 置换 + 多项式exp

    感觉我的做法并不是最优做法... 考虑一个置换\(g\)中的一个置换环\(S\) 在\(g^n\)的形态中,它变为了\(gcd(n, |S|)\)个长度相同的置换环 那么,我们考虑对\(f\)的所有置 ...

  8. 洛谷.1110.[ZJOI2007]报表统计(Splay Heap)

    题目链接 附纯SplayTLE代码及主要思路: /* 可以看做序列有n段,Insert是每次在每一段最后插入一个元素 只有插入,没有删除,所以插入一个元素对于询问1影响的只有该元素与前边一个元素(同段 ...

  9. 专业方向系列-00-Python与有限元初探

    案例1 给出4个弹簧的劲度系数,离散后,求其总的刚度矩阵. 代码: import numpy as np k1, k2, k3, k4 = 500, 250, 2000, 1000 ki = np.a ...

  10. 潭州课堂25班:Ph201805201 爬虫基础 第十三课 cookie (课堂笔记)

    # -*- coding: utf-8 -*- # 斌彬电脑 # @Time : 2018/9/15 0015 4:52 #cookie 是服务器发给浏览器的特殊信息 # 可以理解为一个临时通行证 # ...