"快速排序"算法-之通俗易懂全面解析

1.概念和特点介绍

   要说到几个java的经典算法,快速排序不得不提,这个高效和快速的算法一直是每个java学习者必会的算法,该算法结合递归进行,下面我就详细的通过代码和图片的方式给大家讲解快速排序,希望能帮组想要学习的朋友.
   开始写代码之前我可以告诉朋友们,快速算法到底有多快,举个例子(大家可用试试),随机产生50万个1-100的随机数值,分别放入数组,如果用插入排序,所花的时间大概是90多秒,快速排序呢?两秒不到!一般是半秒到一秒多之间,所以这就是为什么把它成为快速算法的原因.
   我们在开发过程中用到的数组工具Arrays.sort(int[] arr)就是采用的快速算法,那么现在我们就通过代码学习来详细的认识该算法吧.

2.图解分析过程

通过一个图给大家分析一下
这里写图片描述

如果还有不明白过程的朋友,再看看下面一张图就能理解了
这里写图片描述


3.详细代码

下面通过代码的形式给大家写出进行快速排序的详细过程

/**
 * 使用工具Arrays.sort(int[] arr)里边就是快速排序;
 *      快速排序(重点是找mid值,找到一个mid就相当于找到固定了一个数的位置了)
 *      1.定义一个基数,最右边的
 *      2.从左边找第一个比基数大的
 *      3.从右边找第一个比基数小的
 *      4.找到就换角标对应的值
 *      5.继续找 如果找到了,并交叉了left和right就让left和temp互换,就找到一个mid了 如果到不到就判断left和right的关系
 *      6.找到mid就继续递归
 *
 */
public class Demo06 {
    public static void main(String[] args) {
        //定义一个数组
        int[] ints = { 5, 3, 2, 1, 4 };
        //排序前打印一下
        printUtils.printArray(ints);
        quicklySort(ints);
        //排序后再打印一下
        printUtils.printArray(ints);

    }
    //给方法传入数组
    private static void quicklySort(int[] ints) {
        //确定数组的首位和末位置
        sort(ints, 0, ints.length - 1);
    }

    // 为了获取mid
    private static void sort(int[] ints, int left, int end) {
        //方法如果发现left>end了说明越界了,结束即可
        if (left > end) {
            return;
        }
        //定义一个方法专门找中间值
        int mid = findMiddle(ints, left, end);
        //找到了中间值,递归左一半
        sort(ints, left, mid - 1);
        //递归右一半
        sort(ints, mid + 1, end);
    }

    private static int findMiddle(int[] ints, int left, int end) {
        int mid = -1;
        //右边值等于倒数第二个
        int right = end - 1;
        //基数等于最后一个
        int temp = ints[end];
        /*--------------1.死循环找mid--------------*/
        //循环获取所有的固定mid
        while (true) {
            /*--------------2.循环防越界找大小--------------*/
            // 1.从左边找比temp大的
            while (left < end && !(ints[left] > temp)) {//left<end防越界
                left++;
            }
            // 2.从右边找比temp小的
            while (right > left && !(ints[right] < temp)) {//right>=left防越界
                right--;
            }
            /*--------------判断是否到达左角标是否到达右边--------------*/
            if (left == end) {// 超过了end,说明没有比end更大的了
                mid = end;
                return mid;
            }

            if (left < right) {// 找到了但未交叉,换角标值
                int tem = ints[left];
                ints[left] = ints[right];
                ints[right] = tem;
            } else {// 交叉
                int tem = ints[end];
                ints[end] = ints[left];// left角标值 和 temp换
                ints[left] = tem;
                mid = left;// 得到mid
                return mid;
            }
        }
    }
}


写法二:就是不封装找mid的方法,直接写在一起

public class Example2 {
    public static void main(String[] args) {
        int[] ints = initUtils.initData(10);

        printUtils.printArray(ints);
        quicklySort(ints);
        printUtils.printArray(ints);
    }

    private static void quicklySort(int[] ints) {
        sort(ints, 0, ints.length - 1);
    }

    private static void sort(int[] a, int left, int end) {
        if (left > end)
            return;// 如果left>end,停止

        int mid = -1;
        int right = end - 1;
        int start = left;
        int temp = a[end];
        //***注意如果不想通过放在finMid()方法找mid,而是直接这样写,那么就用一个star代替left,因为递归sort(里的left)要和第一次方法里的left相同,所以用start代替.
        while (true) {
            while (start < end && !(a[start] > temp))
                start++;// 防越界和循环找到
            while (right > start && !(a[right] < temp))
                right--;

            if (start == end) {
                mid = end;
                break;
            }
            if (start < right) {//换left right对应值
                int tem = a[start];
                a[start] = a[right];
                a[right] = tem;

            } else {//交叉left temp
                int tem = a[start];
                a[start] = a[end];
                a[end] = tem;
                mid = start;
                break;
            }
        }
        sort(a, left, mid - 1);
        sort(a, mid + 1, end);
    }
}

4.总结

快速排序,重点就是要记住3步:
    1.确定基数(最右边),从左找第一个比基数大的,从右边找第一个比基数小的.
    2.替换left和right对应的值,继续找,交叉后替换left的和基数对应的值,此时即可确定mid
    3.有了mid就把数组分成了两半,此时采用递归:左边left到mid-1;右边mid+1到end,即可轻松完成快速排序.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值