首页 > 编程语言 > 算法之快速排序5非递归实现

算法之快速排序5非递归实现

时间:2023-12-10 18:32:55浏览次数:35  
标签:endIndex arr 递归 int startIndex param mark 算法 排序

一:概述

绝大多数的递归逻辑都可以利用栈的方式去代替。代码中一层一层的方法调用,本身就是使用一个方法调用栈。每次进入一个新的方法,就相当于入栈。每次有方法返回就相当于出栈。

所以,可以把原本的递归实现转换成一个栈的实现,在栈中存储每一次方法调用的参数。

                                   算法之快速排序5非递归实现_入栈


二:具体代码实现

/*
  非递归实现快速排序
 */
public class Sort6 {
      public static void quickSort(int[] arr, int startIndex,int endIndex) {
          // 用一个集合栈来代替递归的函数栈
          Stack<Map<String, Integer>> quickSortStack = new Stack<Map<String, Integer>>();

          // 整个数列的起止下标,以哈希的形式入栈
          Map rootParam = new HashMap();
          rootParam.put("startIndex", startIndex);
          rootParam.put("endIndex", endIndex);
          quickSortStack.push(rootParam);

          // 循环结束条件:栈为空时
          while(!quickSortStack.isEmpty()) {
              // 栈顶元素出栈,得到起止下标
              Map<String, Integer> param = quickSortStack.pop();
              // 得到基准元素位置
              int pivotIndex = partition(arr, param.get("startIndex"),param.get("endIndex"));
              // 根据基准元素分成两个部分,把每一部分的起止下标入栈
              if(param.get("startIndex") < pivotIndex - 1) {
                  Map<String, Integer> leftParam = new HashMap<String, Integer>();
                  leftParam.put("startIndex", param.get("startIndex"));
                  leftParam.put("endIndex", pivotIndex);
              }
              if(pivotIndex + 1 < param.get("endIndex")) {
                  Map<String, Integer> rightParam = new HashMap<String,Integer>();
                  rightParam.put("startIndex", pivotIndex + 1);
                  rightParam.put("endIndex", param.get("endIndex"));
                  quickSortStack.push(rightParam);

              }



          }
      }

     public static int partition(int[] arr, int startIndex, int endIndex)
     {
         // 取第1个位置(也可以选择随机位置)的元素作为基准元素
         int pivot = arr[startIndex];
         int mark = startIndex;

         for(int i = startIndex + 1; i <  endIndex;i++) {
             if(arr[i] < pivot) {
                 mark ++;
                 int p = arr[mark];
                 arr[mark] = arr[i];
                 arr[i] = p;
             }
         }

         arr[startIndex] = arr[mark];
         arr[mark] = pivot;
         return mark;

     }


public static void main(String[] args) {
    int[] arr = new int[] {4, 7, 6, 5, 4, 3, 2, 8, 1};
    quickSort(arr, 0 ,arr.length - 1);
    System.out.println(Arrays.toString(arr));
      }


}

                                   算法之快速排序5非递归实现_方法调用_02

和之前的递归相比非递归的方式代码变动只发生在quickSort中。该方法引入了一个存储Map类型元素的栈,用于存储每一次交换的起始下标和结束下标。

每一次循环,都会让栈顶的元素出栈,通过partition方法进行分治,并且按照基准元素的位置分成左右两个部分,左右两个部分再分别入栈。当栈为空时,说明排序已经完毕。





标签:endIndex,arr,递归,int,startIndex,param,mark,算法,排序
From: https://blog.51cto.com/u_15912723/8762289

相关文章

  • 扩展欧几里得算法
    扩欧代码(时间复杂度O(logn))求ax+by=gcd(a,b)的一组整数解 intgcd(inta,intb){ if(b==0)returna; returngcd(b,a%b);}intexgcd(inta,intb,int&x,int&y){ if(b==0) { x=1,y=0; returna; } intx1,y1,d; d=exgcd(b,a%b,x1,y1); x=y1,y=x1-a/b*y1; re......
  • 算法竞赛模板整理
    图论最短路structSPFA{vector<i64>dis;vector<bool>vis;vector<int>from;intn;SPFA(vector<vector<pair<int,i64>>>&g,ints):n(g.size()){dis.assign(n,INF),vis.assign(n,false),f......
  • 学C笔记归纳 第十篇——循环算法优化
    练习1:求1!+2!+...+10!一般算法:双层循环,外层1~10,内层计算每个数的阶乘,在外层把阶乘相加。intmain(){inti=0;intj=0;intjc=1;intsum=0;for(i=1;i<=10;i++){jc=1;//for(j=1;j<=i;j++){......
  • python算法
    目录: 回溯算法:  回溯算法:一般模型:results=[]defbacktrack(路径,选择列表):passif路径结束,满足约束条件:results.append(路径)#保存结果return#注意,返回到上一个分支,而不是返回结果,退出回溯if路径结束,不满足约束条件:......
  • 插入排序详解
    算法思想把数列分成两部分,前面部分为有序区,后面部分为无序区,初始时有序区只有一个元素,一个数字组成的数列当然是有序的;遍历无序区,把其中每个数不断地插入有序区,形成一个更大的有序区,遍历完成时整个数列也就有序了!学习过程思想(1)两层for循环,第一层for循环是无序区,第......
  • 人工智能基础 - 机器学习算法分类
    监督学习在监督式学习下,输入数据被称为“训练数据”,每组训练数据有一个明确的标识或结果,如对防垃圾邮件系统中“垃圾邮件”“非垃圾邮件”,对手写数字识别中的“1“,”2“,”3“,”4“等。在建立预测模型的时候,监督式学习建立一个学习过程,将预测结果与“训练数据”的实际结果进行比较,不......
  • .net中加解密用BouncyCastle就够了,支持常用的各种加密解密算法
    BouncyCastle是一个流行的Java加解密库,也支持在.NET平台上使用。下面是BouncyCastle在.NET下使用的一些常见功能,包括AES、RSA、MD5、SHA1、DES、SHA256、SHA384、SHA512等。在开始之前,请确保你已经将BouncyCastle的NuGet包安装到你的项目中。你可以通过NuGet......
  • 深度解读DBSCAN聚类算法:技术与实战全解析
    探索DBSCAN算法的内涵与应用,本文详述其理论基础、关键参数、实战案例及最佳实践,揭示如何有效利用DBSCAN处理复杂数据集,突破传统聚类限制。关注TechLead,分享AI全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里......
  • Java之包装类的算法小题的练习
     算法小题练习一:需求:键盘录入一些1~10日之间的整数,并添加到集合中。直到集合中所有数据和超过200为止。代码示例:publicclassTest1{publicstaticvoidmain(String[]args){/*键盘录入一些1~10日之间的整数,并添加到集合中。直到集合中所有数据和超......
  • 贪心算法
    1.贪心算法1.电台覆盖区域求最优解问题题目:假设存在如下表的需要付费的广播台,以及广播台信号可以覆盖的地区。如何选择最少的广播台,让所有的地区都可以接收到信号广播台覆盖地区K1“北京”,“上海”,“天津”K2“广州”,“北京”,“深圳”K3“成都”,......