快速排序

你也许会被快速排序的文章弄得迷迷糊糊,其实大体上去看,快速排序就一步:找个数做基准数,把小于它的数移到它左边,把大于它的数移到它右边。这句话是核心。然后我们只需要让基准数左边的重复上面的步骤,让基准数右边的再重复上面的步骤就完了。

比如我们有一个数组:

    int[] nums = {5, 2, 6, 8, 4, 7, 9, 1};

快速排序的思想就是使用递归,其实使用递归并不是多么复杂,在理解算法的思想后,只需要关注算法中重复的步骤,那就是递归的核心代码。

比如快速排序的算法思想,大体代码如下:

public void quick(int left, int right) {
    /*
    * 给这段代码起个名字为:基准校验
    * 把小于基准数的移到左边,把大于基准数的移到右边
    */
    quick(left, now); //继续处理左边的
    quick(now, right); //继续处理右边的
}

经过一遍基准校验,我们就找到了该基准数在完全排序后的正确位置!

大体算法的流程图:

写出上面的大体算法步骤,就表示我们已经有了雏形,现在该如何实现找个数做基准数,把小于它的数移到它左边,把大于它的数移到它右边呢?

排除不满足的情况:

        //已经不满足条件就代表可以不用递归了
        if (left > right) {
            return;
        }

我们可以定义两个指针,用于遍历数组:

        int start = left;//起点下标
        int end = right;//终点下标

再找一个基准数:

        int temp = nums[left];//把第一个数作为基准点

遍历代码:

 /*如果左右指针还没有走到一起,代表还有位置没有遍历*/
 while (start != end) {
     //右指针先走,找到小于基准数的停止
     while (start < end && nums[end] >= temp) {
         end--;     //这是往左移动指针
     }
     //左指针后走,找到大于基准数的停止
     while (start < end && nums[start] <= temp) {
         start++;  //这是往右移动指针
     }
     //如果左右指针在未相遇时都找到了目标,则交换位置
     if (start < end) {
         int i = nums[start];
         nums[start] = nums[end];
         nums[end] = i;
     }
     //左右指针走到一起,则遍历结束
 }
 //把基准数与该点交换位置,因为这就是基准数的正确位置
 nums[left] = nums[start];
 nums[start] = temp;

如果还是不太清楚,不如自己动手试试!

拷贝完整代码:

    //定义一个数组
    static int[] nums = {5, 2, 6, 8, 4, 7, 9, 1};
    static int n = nums.length - 1;

    /**
     * 递归的数据结构就是栈
     * left right代表该段数组的起点和终点
     */
    public void quick(int left, int right) {
        //已经不满足条件就可以不用递归了
        if (left > right) {
            return;
        }
        //定义俩指针 用于移动
        int start = left;//起点下标
        int end = right;//终点下标
        int temp = nums[left];//把第一个数作为基准点

        pri(left, right);//打印此时的结果,不用在意

        while (start != end) {    //如果左右指针还没有走到一起,代表还有位置没有遍历
            while (start < end && nums[end] >= temp) { //右指针先走,找到小于基准数的停止
                end--;            //这是往左在移动指针
            }
            while (start < end && nums[start] <= temp) { //左指针后走,找到大于基准数的停止
                start++;     //这是往右在移动指针
            }
            if (start < end) {    //如果左右指针在未相遇时都找到了目标,则交换位置
                int i = nums[start];
                nums[start] = nums[end];
                nums[end] = i;
            }
        }
        //此时的left和right走到了一起
        //把基准数与该点交换位置
        nums[left] = nums[start];
        nums[start] = temp;

        prin(start);//打印输出,不用在意

        //以上代码的作用就是把小于基准数的移到左边,把大于基准数的移到右边
        quick(left, start - 1); //继续处理左边的,这里是一个递归的过程
        quick(start + 1, right); //继续处理右边的 ,这里是一个递归的过程

    }

    /**
    * 主程序入口
    */
    public static void main(String[] args) {
        new Test().quick(0, n);
    }

    /**
     * 以下代码忽略即可,用于打印输出
     */
    private void pri(int start, int end) {
        StringBuffer s = new StringBuffer();
        s.append("对数组 [");
        while (start <= end) {
            s.append(nums[start] + " ");
            start++;
        }
        s.append("]");
        s.append(" 排序");
        System.out.print(s);
    }

    private void prin(int j) {
        StringBuffer s = new StringBuffer();
        s.append(", 排序后 [");
        int start = 0;
        while (start <= n) {
            if (start == j) {
                s.append("(" + nums[start] + ") ");
            } else {
                s.append(nums[start] + " ");
            }
            start++;
        }
        s.append("]");
        s.append(" ");
        System.out.println(s);
    }

打印输出:

对数组 [5 2 6 8 4 7 9 1 ] 排序, 排序后 [4 2 1 (5) 8 7 9 6 ]
对数组 [4 2 1 ] 排序, 排序后 [1 2 (4) 5 8 7 9 6 ]
对数组 [1 2 ] 排序, 排序后 [(1) 2 4 5 8 7 9 6 ]
对数组 [2 ] 排序, 排序后 [1 (2) 4 5 8 7 9 6 ]
对数组 [8 7 9 6 ] 排序, 排序后 [1 2 4 5 6 7 (8) 9 ]
对数组 [6 7 ] 排序, 排序后 [1 2 4 5 (6) 7 8 9 ]
对数组 [7 ] 排序, 排序后 [1 2 4 5 6 (7) 8 9 ]
对数组 [9 ] 排序, 排序后 [1 2 4 5 6 7 8 (9) ] 

让你一看就懂的快速排序算法(Java)的更多相关文章

  1. 快速排序算法 java 实现

    快速排序算法 java 实现 快速排序算法Java实现 白话经典算法系列之六 快速排序 快速搞定 各种排序算法的分析及java实现 算法概念 快速排序是C.R.A.Hoare于1962年提出的一种划分 ...

  2. 排序算法系列:快速排序算法JAVA版(靠谱、清晰、真实、可用、不罗嗦版)

    在网上搜索算法的博客,发现一个比较悲剧的现象非常普遍: 原理讲不清,混乱 啰嗦 图和文对不上 不可用,甚至代码还出错 为了不误人子弟耽误时间,推荐看一些靠谱的资源,如[啊哈!算法]系列: https: ...

  3. 排序系列 之 快速排序算法 —— Java实现

    基本思想: 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变 ...

  4. 【排序算法】快速排序算法 Java实现

    快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序.它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod). 基本思想 先从数组中找出一个数作为基 ...

  5. 快速排序算法Java版

    网上关于快速排序的算法原理和算法实现都比较多,不过java是实现并不多,而且部分实现很难理解,和思路有点不搭调.所以整理了这篇文章.如果有不妥之处还请建议.首先先复习一些基础.    1.算法概念. ...

  6. 快速排序算法Java实现

    1) 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行 示例: package ...

  7. 一看就懂的Android APP开发入门教程

    一看就懂的Android APP开发入门教程 作者: 字体:[增加 减小] 类型:转载   这篇文章主要介绍了Android APP开发入门教程,从SDK下载.开发环境搭建.代码编写.APP打包等步骤 ...

  8. mysql取出现在的时间戳和时间时间戳转成人类看得懂的时间

    mysql取出现在的时间戳和时间时间戳转成人类看得懂的时间,我们在mysql里面他封装了一个内置的时间戳转化的函数,比如我们现在的时间戳是:1458536709 ,"%Y-%m-%d&quo ...

  9. 一看就懂的ReactJs入门教程(精华版)

    一看就懂的ReactJs入门教程(精华版) 现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和 ...

随机推荐

  1. WPF:自定义Metro样式文件夹选择对话框FolderBrowserDialog

    1.前言 WPF并没有文件选择对话框,要用也就只有使用Winform版的控件.至今我也没有寻找到一个WPF版本的文件选择对话框. 可能是我眼浊,如果各位知道有功能比较健全的WPF版文件选择对话框.文件 ...

  2. hdu-2018题(母牛问题)

    HDU-2018题/*有一头母牛,它每年年初生一头小母牛.每头小母牛从第四个年头开始,每年年初也生一头小母牛.请编程实现在第n年的时候,共有多少头母牛?Input输入数据由多个测试实例组成,每个测试实 ...

  3. JHipster开发环境安装

    本文演示如何在CentOS7上安装Jhipster以及其依赖组件. 这里采用官方推荐的Yarn安装方法,操作系统版本为CentOS 7.4. 1 安装JDK 推荐版本:OpenJDK 1.8.0-64 ...

  4. 使用Visual Studio Team Services敏捷规划和项目组合管理(五)——组合管理

    使用Visual Studio Team Services敏捷规划和项目组合管理(五)--组合管理 组合待办事项为产品所有者提供关于几个敏捷特性团队工作的洞察.产品所有者可以将高优先级的目标定义为Ep ...

  5. 使用Visual Studio Team Services敏捷规划和项目组合管理(二)——VSTS中的工作项

    使用Visual Studio Team Services敏捷规划和项目组合管理(二)--VSTS中的工作项 1.通过project/team下拉菜单选择MyHealthClinic\Web,导航到W ...

  6. spring4笔记----spring4设值注入

    2个接口 package com.ij34.servce; public interface people { public void cut(); } package com.ij34.servce ...

  7. [20170607]再论Private Strand Flush Not Complete.txt

    [20170607]再论Private Strand Flush Not Complete.txt --//曾经跟zergduan有过讨论,链接www.itpub.net/thread-2065703 ...

  8. ArcGIS Server服务器监控

    最近项目上需要对服务器与ArcGISServer服务进行监控,做了一个初步的原型,实现了以下功能. 一.服务器监控 注册服务器 服务器运行状态监控 在线状态 CPU.内存.存储配置监控,由于现在很多采 ...

  9. 探索SQL Server元数据(三):索引元数据

    背景 在第一篇中我介绍了如何访问元数据,元数据为什么在数据库里面,以及如何使用元数据.介绍了如何查出各种数据库对象的在数据库里面的名字.第二篇,我选择了触发器的主题,因为它是一个能提供很好例子的数据库 ...

  10. Android音频系统

    1 分析思路 Thread如何创建? AudioPolicyService是策略的制定者,AudioFlinger是策略的执行者, 所以: AudioPolicyService根据配置文件使唤Audi ...