快速排序

shuyepl 2022-04-09 22:25:12
Categories: > Tags:

内容简介:Java 语言实现快速排序

网上看到的实现快速排序的方法比较多的是以数组第一个数为标准值进行排序的方式,内种方式是左右两边各有一个指针(Java 里面不应该说指针,这里这是这样说比较好理解而已,可以理解为是一个代表数组下标的东西),在开始的时候分别指向数组的开头和结尾,指向开头的指针从左到右在数组中遍历,找到一个比标准值大的数字的时候就停下来,指向它,这个时候,刚开始指向右边的指针就开始动了,从右往左扫描,找寻比标准值小的数字,这个时候,两个找到的数字交换,交换完成之后,左边依旧找比标准值大的数字,右边依旧找比标准值小的数字,交换 … … 直到两个指针指向同一个数字未知,此时,将标准值与这个位置上的数字交换,当完成这一步的时候,以标准值为中心,左边的数字都是小于标准值的,右边的数字都是大于标准值的,此时,将这个数组已标准值为中心,分别对其左边部分和右边部分进行上述的过程,那么这两部分的数组而言,也会和上面一样 ,以一个标准值为中心,分为比它大的部分和比它小的部分,如此,我们适当想像一下,如果,一直这么分割下去,整个数组就会变得越来越有序,数组中的数据依照从小到大的顺序排列起来。

而与上面的方法有点类似的,老师采用的方法 ,是以数组中间的数据为标准值,从左往右的顺序先找比标准值大的数据,再找比标准值小的数据,交换位置,但与上面有点不一样的地方是,在找数据的过程中,上面的方式只会对标准值进行一次交换,而老师的这种方法,在左右两个指针有一个指向标准值的时候,另外的一个指针就会找相应要找的数据,与这个标准值进行交换,最终,这个标准值可能会交换很多次,这个地方也是我刚开始听老师的课时始终无法理解的一个地方,因为我一直以为这个地方中,标准值不需要进行交换,但最后我拿起笔和纸将数组写在纸上,跟着代码一步一步模拟程序的运行的时候,才发现,其实,标准值的位置是一直有在改变的。

具体老师的代码如下,好好理解的话还是可以看懂的。

package com.atguigu.sort.QuickSort;

public class QuickSort {
    public static void main(String[] args) {
        int[] arr = {-9,78,0,23,-567,70, -1, -2,};
        quickSort(arr, 0, arr.length - 1);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
    public static void quickSort(int[] arr, int left, int right) {
        int l = left;
        int r = right;
        int pivot = arr[(left + right) / 2];
        int temp = 0;
        /* 这里在看视频的时候以为以中间的数字为基准,那么中间的数字就不会移动,理解的很久,最后,在纸和笔的帮助下,才发现,其          实中间的那个标准值是有在移动地方的,所以,最终并不会发生因为中间值左右两边大于标准值和小于标准值的数据量不同而发生              错误。
           果然纸和笔是YYDS
         */
        while(l < r){
            /*
            这里的两个循环的作用最主要就是找到可以交换的数字,一个比标准值大的,和一个标准值小的
            注意这里循环里面的条件从左边开始找比标准值大的或者等于标准值的,这个等于标准值很重要,
            这里是解决左右两边数据量不等的情况的地方之一
             */
            while(arr[l] < pivot){
                l++;
            }
            while(arr[r] > pivot){
                r--;
            }
            // 有可能一上来就直接找到中间的值了,所以,退出的判断条件要放在这个地方
            if(l >= r){
                break;
            }
            // 没达到退出的条件,就交换数据,没什么好说的样子
            temp = arr[r];
            arr[r] = arr[l];
            arr[l] = temp;
            // 这个地方就是重点了,如果数据量不等的话,那么这里就是找到能和标准值交换位置的地方,和标准值交换位置
            if(arr[l] == pivot){
               r--;
            }
            if(arr[r] == pivot){
                l++;
            }
        }
        // 这一段代码是用来解决栈溢出问题的,这种情况经过有限次分割之后,
        // 那个分割下来的数组不会改变了,一直都是那么长的数组,一直无限递归下去
        if(l == r){
            l++;
            r--;
        }
        // 脑子中对这个数组的情况要构建出一个大概的样子,再看这段代码,还是很好理解的
        if(left < r){
            quickSort(arr, left, r);
        }
        if(right > l){
            quickSort(arr, l, right);
        }
    }
}

参考资料:【尚硅谷】数据结构与算法(Java数据结构与算法)_哔哩哔哩_bilibili