快排Java实现

news/2024/5/19 22:49:55 标签: 算法, 快速排序, java

快排实现

  • 1. 思路
  • 2. 实现

1. 思路

  • 快排是基于分治思想
    在数组中选中某个数值为基准,左边大于等于基准,右边小于等于基准。
    这里就不举例子了,网上类似的文章很多,这篇文章主要是剖析快排算法的实现

2. 实现

这里将会罗列两种写法,可以仔细对比两者区别,就能够更好地理解快排的思想。

  1. 这是一种写法:
java">public class QuitSort {

    public static void sort(int[] num) {
        sort(num, 0, num.length - 1);
    }

    private static void sort(int[] num, int left, int right) {
        //递归终止条件
        if (left >= right) {
            return;
        }
        //这里设置左边第一个元素为基准值,当然也可以设置右边为基准值,只是实现代码不一样
        int pos = num[left];
        //双指针法,分别指向 left 和 right
        int l = left;
        int r = right;

        //双指针遍历终止条件
        while (l < r) {
            /**
             * 这里有考究,可以看下面的例子,当上一次循环 left 和 right 指向如下
             *             那么判断的顺序就至关重要了,如下代码,可以预测,当退出 while 循环时,
             *              left 和 right 同时指向了 0
             *
             *                      left right
             *                        |    |
             *              1    2    0    4    6    3
             */
            if (num[r] > pos) {
                r--;

                /**
                 * 这里的 >= 为什么不可以替换为 > ?
                 * 因为我们必须保准基准值nums[left] == pos
                 * 假如 替换成 >
                 * 那么 nums[left] != pos
                 * 将会导致我们无法将pos置于中间位置
                 */
            } else if (num[l] <= pos) {
                l++;
            } else {//交换数值
                int tmp = num[l];
                num[l] = num[r];
                num[r] = tmp;
            }
        }
        /**
         * 此时nums[left] == pos
         * nums[l] 指向 小于 pos 的值
         * nums[l+i] 全都 大于 pos
         * 我们把nums[left] 与 nums[l] 交换位置,就可以实现"nums[l] == pos,并且左边全都小于等于pos,右边全都大于pos"
         */

        num[left] = num[l];
        num[l] = pos;

        /**
         * 递归分治
         */
        sort(num, left, l - 1);
        sort(num, l + 1, right);

    }

    public static void main(String[] args) {
        int CAPACITY = 100;
        int[] test = new int[CAPACITY];
        for (int i = 0; i < CAPACITY; i++) {
            test[i] = (int) (Math.random() * CAPACITY);
        }
        sort(test);
        System.out.println(Arrays.toString(test));
    }
}
  1. 这是第二种实现
java">public class QuitSort {

    public static void sort(int[] num) {
        sort(num, 0, num.length - 1);
    }

    private static void sort(int[] num, int left, int right) {
        if (left >= right) {
            return;
        }
        int pos = num[right];
        int l = left;
        int r = right;

        while (l < r) {
            if (num[l] < pos) {
                l++;
            } else if (num[r] >= pos) {
                r--;
            } else {//交换数值
                int tmp = num[l];
                num[l] = num[r];
                num[r] = tmp;
            }
        }
        num[right] = num[l];
        num[l] = pos;
        sort(num, left, l - 1);
        sort(num, l + 1, right);

    }

    public static void main(String[] args) {
        int CAPACITY = 100;
        int[] test = new int[CAPACITY];
        for (int i = 0; i < CAPACITY; i++) {
            test[i] = (int) (Math.random() * CAPACITY);
        }
        sort(test);
        System.out.println(Arrays.toString(test));
    }
}

咋一看,好像没什么区别,但是我把不同的代码截取下来,就会发现不一样的地方了

  1. 对比
    这是第一种方法:
    在这里插入图片描述
    这是第二种方法:
    在这里插入图片描述
    所以看出来了吧,尽管两种不太一样的实现方法,它们的本质都是
  • 为了保证基准值与中间值进行交换,
  • 为了达到这个目的,还必须保证基准值的位置没有改变!,这就是在比较的时候必须使用>=或者<=的理由!

http://www.niftyadmin.cn/n/1489602.html

相关文章

kafka自定义序列化反序列化

kafka自定义序列化反序列化0. 问题1. 原因分析2. 解决方法3. 结果测试0. 问题 最近在学习kafka的时候碰到一个问题&#xff0c;当我尝试使用kafka发生一个pojo对象时&#xff0c;使用如下配置的时候&#xff0c;发现代码报错了&#xff0c;是类型匹配错误&#xff1a; applica…

自定义注解实现Redis缓存功能

自定义注解实现Redis缓存功能0. 写在最前1. 思路2. 项目搭建3. 注解实现4. 总结0. 写在最前 本文主要作为记录学习Redis的过程&#xff0c;利用自定义注解实现Redis缓存功能。 最近在学习Redis和SpringBoot&#xff0c;本来以为用框架实现缓存是一件比较复杂的事情&#xff0c…

OCA Java SE 7 Programmer I考试——ArrayList

1&#xff09;ArrayList 的clone方法是浅表复制&#xff0c;对于基本数据类型&#xff0c;clone方法复制其值&#xff0c;对于引用数据类型则复制引用 2&#xff09;默认的创建一个ArrayList对象&#xff0c;能存储10个元素 3&#xff09;ArrayList修改了自己的toString&…

OCA Java SE 7 Programmer I考试——Exception,Error

1) Exception的printStackTrace(),getmessage(),toString()方法之间的区别与联系 printStackTrace()&#xff1a;输出第一行包含此对象的toString()方法的结果&#xff0c;剩余行表示以前由方法fillInStackTrace()记录的数据 getMessage():返回此Throwable 或者Exception的详…

Weblogic 12.1.3集群管理手册(简介)

weblogic12c在集群管理方面新增一些特性&#xff0c;但相关知识在oracle官网并未找到相应的中文版本&#xff0c;因此打算简单翻译一下Administering Clusters for Oracle WebLogic Server这个文档&#xff0c;希望对weblogic12.1.3版本集群方面的理解有所帮助&#xff0c;错误…

Weblogic 12.1.3集群管理手册(了解weblogic集群)

2 了解weblogic集群 本章节提供了对weblogic服务器集群的简单介绍。本章节包含以下部分&#xff1a; 2.1 什么是weblogic服务器集群&#xff1f; 2.2 什么是动态集群&#xff1f; 2.3 weblogic集群与weblogic域之间的联系&#xff1f; 2.4 集群有哪些好处&#xff1f; 2.5 集…

Solaris scp Permission denied (gssapi-keyex,gssapi-with-mic,publickey,keyboard-interactive)

Solaris 在不同主机之间进行复制的时候出现Permission denied &#xff0c;通常是目标服务器用户不具备在目标路径下写权限&#xff0c;或者目标服务器用户被禁止ssh登陆。 在Solaris中root用户默认是被禁止ssh登陆的&#xff0c;可以修改配置文件进行更改。 在目标服务器上&…

Weblogic12.1.3集群管理手册(集群中的通信机制)

本章节描述了weblogic集群如何使用IP套接字和IP单播或组播进行通信的。 Weblogic集群中服务实例之间的通信主要使用下面两种网络策略&#xff1a; IP单播或多播&#xff0c;服务器实例使用该技术来广播服务和心跳&#xff08;表明持续的可用性&#xff09;的可用性。IP套接字…