算法之快速排序(递归和非递归)

快速排序的两种实现方式.递归和非递归

  1 package com.ebiz.sort;
  2 
  3 import java.text.SimpleDateFormat;
  4 import java.util.Arrays;
  5 import java.util.Date;
  6 import java.util.Stack;
  7 
  8 /**
  9  * @author YHj
 10  * @create 2019-08-18 17:42
 11  */
 12 public class Quick {
 13 
 14     public static void main(String[] args) {
 15         int[] arr = new int[8];
 16         for (int i = 0; i < 8; i++) {
 17             arr[i] = (int) (Math.random() * 800000);
 18         }
 19 
 20         String s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
 21         System.out.println("排序前 = " + s);
 22 
 23         quickSort(arr,0,arr.length-1);
 24 
 25 
 26         String l = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
 27         System.out.println("排序后 = " + l);
 28     }
 29 
 30     /**
 31      * 快速排序(递归)
 32      * <p>
 33      * ①. 从数列中挑出一个元素,称为"基准"(pivot)。
 34      * ②. 重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
 35      * ③. 递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。
 36      *
 37      * @param arr  待排序数组
 38      * @param low  左边界
 39      * @param high 右边界
 40      */
 41     public static void quickSort(int[] arr, int low, int high) {
 42         if (arr.length <= 0){
 43             return;
 44         }
 45         if (low >= high) {
 46             return;
 47         }
 48         int left = low;
 49         int right = high;
 50 
 51         int temp = arr[left];   //挖坑1:保存基准的值
 52         while (left < right) {
 53             while (left < right && arr[right] >= temp) {  //坑2:从后向前找到比基准小的元素,插入到基准位置坑1中
 54                 right--;
 55             }
 56             arr[left] = arr[right];
 57             while (left < right && arr[left] <= temp) {   //坑3:从前往后找到比基准大的元素,放到刚才挖的坑2中
 58                 left++;
 59             }
 60             arr[right] = arr[left];
 61         }
 62         arr[left] = temp;   //基准值填补到坑3中,准备分治递归快排
 63         System.out.println("Sorting: " + Arrays.toString(arr));
 64         quickSort(arr, low, left - 1);
 65         quickSort(arr, left + 1, high);
 66     }
 67     /**
 68      * 快速排序(非递归)
 69      *
 70      * ①. 从数列中挑出一个元素,称为"基准"(pivot)。
 71      * ②. 重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
 72      * ③. 把分区之后两个区间的边界(low和high)压入栈保存,并循环①、②步骤
 73      * @param arr   待排序数组
 74      */
 75     public static void quickSortByStack(int[] arr){
 76         if(arr.length <= 0){
 77             return;
 78         }
 79         Stack<Integer> stack = new Stack<Integer>();
 80 
 81         //初始状态的左右指针入栈
 82         stack.push(0);
 83         stack.push(arr.length - 1);
 84         while(!stack.isEmpty()){
 85             int high = stack.pop();     //出栈进行划分
 86             int low = stack.pop();
 87 
 88             int pivotIdx = partition(arr, low, high);
 89 
 90             //保存中间变量
 91             if(pivotIdx > low) {
 92                 stack.push(low);
 93                 stack.push(pivotIdx - 1);
 94             }
 95             if(pivotIdx < high && pivotIdx >= 0){
 96                 stack.push(pivotIdx + 1);
 97                 stack.push(high);
 98             }
 99         }
100     }
101 
102     private static int partition(int[] arr, int low, int high){
103         if(arr.length <= 0) {
104             return -1;
105         }
106         if(low >= high) {
107             return -1;
108         }
109         int l = low;
110         int r = high;
111 
112         int pivot = arr[l];    //挖坑1:保存基准的值
113         while(l < r){
114             while(l < r && arr[r] >= pivot){  //坑2:从后向前找到比基准小的元素,插入到基准位置坑1中
115                 r--;
116             }
117             arr[l] = arr[r];
118             while(l < r && arr[l] <= pivot){   //坑3:从前往后找到比基准大的元素,放到刚才挖的坑2中
119                 l++;
120             }
121             arr[r] = arr[l];
122         }
123         arr[l] = pivot;   //基准值填补到坑3中,准备分治递归快排
124         return l;
125     }
126 
127 
128 }

 

转载于:https://www.cnblogs.com/jiushixihuandaqingtian/p/11449371.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/409990.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iCloud官方文档

官方地址&#xff1a;iOS App Programming Guide -> iCloud Storage这个偏理论一些&#xff0c;提供了很多iCloud应用设计层面的东西&#xff0c;大家感兴趣&#xff0c;可以一看。如果需要iCloud上手教程&#xff0c;可以参考我的另外一个贴子&#xff1a;http://www.cocoa…

单片机 架构 程序 经验总结_单片机“死机”了怎么办?看看一个资深工程师的经验总结...

原标题&#xff1a;单片机“死机”了怎么办&#xff1f;看看一个资深工程师的经验总结单片机(Microcontroller&#xff0c;MCU) 又称为微控制器或嵌入式控制器&#xff0c;体积虽小&#xff0c;但使用方便&#xff0c;应用范围广泛&#xff0c;在如通讯设备、智能化管理、医疗设…

[html] 使用canvas制作一个印章

[html] 使用canvas制作一个印章 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</titl…

0x00000000指令引用的内存不能为written_变量和内存访问

计算机世界有一个常识——所有的数据和指令必须经由内存才能进入CPU的寄存器进而被CPU使用&#xff0c;那么我们程序操作的主战场就是内存&#xff0c;内存操作也就顺理成章成为了程序中最高频的操作。为了节目的效果&#xff0c;我们先来看一段8086平台下的汇编代码&#xff1…

Zabbix 3.0 配置企业微信报警(注册---测试)

一、申请企业微信 1、登录企业微信官网&#xff0c;点击企业注册 二、配置企业微信 1、邀请管理员使用企业微信&#xff0c;如果有多个人直接添加新成员 2、管理员收到邀请&#xff0c;下载手机版企业微信&#xff0c;使用微信号登陆即可 3、创建应用 4、填写应用信息&#xff…

centos8 挂载ntfs_CentOS 8 挂载NTFS系统磁盘方案

本文最后更新于2020年4月20日&#xff0c;可能会因为没有后期更新而失效。如果您发现本文已经失效或者需要修正&#xff0c;请留言给博主&#xff01;感谢前言Linux 的系统默认是不支持 NTFS 格式的磁盘的&#xff0c;但总有些场景需要插入 USB、移动硬盘等 NTFS 格式磁盘来做文…

AutoMapper 9.0的改造(续)

上一篇有一个读者&#xff0c;有疑问&#xff0c;如何自动化注册Dto 我开篇&#xff0c;做了一个自动化注册的 public sealed class AutoInjectAttribute : Attribute{public Type SourceType { get; }public Type TargetType { get; }public AutoInjectAttribute(Type sourceT…

.net byte转java byte_Java Web安全 || Java基础 Java Agent

点击上方“凌天实验室”&#xff0c;“星标或置顶公众号”漏洞、技术还是其他&#xff0c;我都想第一时间和你分享“【历史】已连载更新全部内容&#xff1a;【菜单栏】-【JAVA SEC】01Java AgentJDK1.5开始&#xff0c;Java新增了Instrumentation(Java Agent API)和JVMTI(JVM …

ipc$开启telnet

echo offtitle opentelnet cheng...MODE con: COLS44 LINES15:zjmclscolor 0afor /l %%i in (1,1,5) do echo.echo -简介- echo.echo 依靠ipc$来开启Telnet!echo 请按提示输入...echo.set/p ip 输入IP: if /i "%ip%"&…

maven 修改文件名_Maven 构建配置文件

Maven 构建配置文件构建配置文件是一系列的配置项的值&#xff0c;可以用来设置或者覆盖 Maven 构建默认值。使用构建配置文件&#xff0c;你可以为不同的环境&#xff0c;比如说生产环境(Production)和开发(Development)环境&#xff0c;定制构建方式。配置文件在 pom.xml 文件…

必须进行支持的游戏方可使用此功能_C#8.0 新增功能

(给DotNet加星标&#xff0c;提升.Net技能)转自&#xff1a;张传宁cnblogs.com/SavionZhang/p/11201818.htmlC#8.0提供了许多增强功能1、Readonly 成员可将 readonly 修饰符应用于结构的任何成员。它指示该成员不会修改状态。这比将 readonly 修饰符应用于 struct 声明更精细。…

FOR JENNIFER MORRISON

豪斯医生里面这女子真是感觉越来越好看了&#xff0c;唉~ 白天一直在写代码&#xff0c;感觉自己非常2B&#xff0c;选择了一个非常臃肿容易出错的方式来完成一个本来很容易的问题。 那就是用状态机嵌套&#xff0c;大的状态机来操作整个模块的动作是没有错误的&#xff0c;但是…

Zabbix 3.0 配置企业微信报警(配置zabbix-web)

一、添加报警媒体类型 Name&#xff1a;自定义 Type&#xff1a;选择script Scripts name&#xff1a;填写脚本名称 Script parameters&#xff1a;脚本参数--corpidXXX--corpsecretXXX--user{ALERT.SENDTO}--msg{ALERT.MESSAGE}--agentidXXX最后点Add即可添加完成&#xff1b;…

[html] 写个布局,当页面高度不够时,底部固定在下面,反之不固定

[html] 写个布局&#xff0c;当页面高度不够时&#xff0c;底部固定在下面&#xff0c;反之不固定 <div class"layout"> <header class"header"><!-- header 内容 …… --></header><div class"page"><slot /…

信号量与令牌桶_限流的4种方式令牌桶实战

限流的4种方式正文限流限流是对某一时间窗口内的请求数进行限制&#xff0c;保持系统的可用性和稳定性&#xff0c;防止因流量暴增而导致的系统运行缓慢或宕机。常用的限流算法有令牌桶和和漏桶&#xff0c;而Google开源项目Guava中的RateLimiter使用的就是令牌桶控制算法。在开…

采用python解决实际问题_Python编程语言解决几种常见的实际问题

Python编程语言解决几种常见的实际问题 (2012-10-25 17:24:12) 标签&#xff1a; it python python培训 北京 杂谈 Python编程语言解决一些实际问题 from os.path import walk, join, normpath from os import chdir, remove def scan(arg, dirname, names) for file in names:…

EevExpress中XtraGrid常用方法

1.girdView在第一列显示行号 调整第一列的宽度 gridView1.IndicatorWidth 40; View Code 1 private void gridView1_CustomDrawRowIndicator(object sender, DevExpress.XtraGrid.Views.Grid.RowIndicatorCustomDrawEventArgs e)2 { 3 if (e.Info.IsRowIndi…

【转载】博客园编辑数学公式的方法

原文在这里&#xff1a;博客园编辑数学公式的方法 需要在选项中勾上 启用数学公式支持 在公式开始和结尾输入美元符号 &#xff1a; 如 美元符号x^2美元符号 则显示x的平方 x^2 需要在http://latex.codecogs.com/eqneditor/editor.php里面编辑好后复制源码过来。 如 转载于:htt…

[html] 使用递归时应该注意哪些问题?

[html] 使用递归时应该注意哪些问题&#xff1f; 必须要有正确的结束条件避免占用太多栈而爆掉&#xff0c;可限制最大栈数报警或异步分批注意类似对象引用自身的无限循环情况个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很…