基础算法——快速排序

想要变优秀,顺其自然是不可能的
你需要做很多,花很多时间,忍耐并且坚持。

快速排序,简称快排,也是初级面试里面被问到最多的排序算法,在普通使用情况下(数据基本无序,数据量n巨大),相对于直接插入排序,简单选择排序,冒泡法排序,快速排序的效率都会更优。这是由冒泡排序改进的算法,也是一种基于交换排序的算法,但是不同于冒泡排序,冒泡排序每次只比较交换相邻的两个元素,每次只消除两个元素之间的逆序,但是快速排序通过两个相邻或者不相邻的元素的交换,能消除多个逆序,极大地加快排序的速度。

下面是每次进行冒泡排序时的模式,这个过程中,因为每次只会交换相邻两个元素的位置,所以只会修改这两个元素的顺序

基础算法——快速排序_第1张图片
冒泡排序交换模式

相对于快速排序,一次可能消除多个逆序的情况,随机选择一个记录anchor(一般选择第一个元素),通过一趟排序把比anchor大的值放到右子表,比anchor小的值放到左子表,再对左右子表使用同样的方式进行划分,直到每个子表都只有一个元素。
对于每一趟循环,首先设定low和high指向左右两个边界:
1、比较右边界high和anchor的大小,如果high大于anchor的值,那么high--,如果是小于anchor的值,那么交换anchor和high的位置,如果找到了比anchor小的值,那么到达第2步
2、比较左边界low和anchor的大小,如果low小于anchor的值,那么low++,如果是大于anchor的值,那么交换anchor和low的位置,返回第1步
3、重复第1步和第2步,直到low == high为止。

基础算法——快速排序_第2张图片
Paste_Image.png

刚好碰巧第一个元素就是整个数组最小的,这里我们也看到了,要是元素最小的话,那么效率就跟普通的冒泡排序差不多一样了。如果我们的序列一开始就是基本有序的,快速排序算法(一次交换消除多个元素的逆序)的优势就不明显了。

    private static int Partition(int[] num,int low,int high){
        int anchor = num[low];  //用第一个元素作为anchor
        //当low == high的时候退出循环
        while(low = num[low]) low++;
            //当前的low值大于anchor,让low位置的值移动anchor的位置
            num[high] = num[low];
        }
        //跳出循环时,anchor不再移动
        num[high] = anchor;
        return high;
    }
    
    
    private static void QuickSort(int[] num,int low,int high){
        if (low < high) {
            //第一趟排序后anchor的位置
            int index = Partition(num, low, high);
            QuickSort(num, low, index - 1);
            QuickSort(num, index+1, high);
        }
    }

算法特点

最好的情况是待排序的集合无序,最坏情况带排序集合基本有序,平均情况下的时间复杂度为O(nlogn),空间复杂度最好情况下为O(logn),最坏情况为O(n),适用于初始记录无序,n较大的情况。

你可能感兴趣的:(基础算法——快速排序)