Java排序算法 - 快速排序

快速排序算法

思路:選擇基準(zhǔn)數(shù),將所有小于基準(zhǔn)數(shù)的移動到基準(zhǔn)數(shù)的左邊,大于的移動到右邊,之后采用分治思想,遞歸調(diào)用。

步驟如下:

首先,需要一個待排序的數(shù)組。

待排序數(shù)組

將第一個數(shù),也就是8作為基準(zhǔn)數(shù),分別在數(shù)組頭和尾各設(shè)置一個哨兵A和B。
哨兵A和B

哨兵B負(fù)責(zé)向左移動,找到一個小于基準(zhǔn)數(shù)的值之后停下,將值B位置的值賦值給A所在位置,也就是將8改成7,將A的位置向后移動一位。(因?yàn)槟康氖菍⑿∮诨鶞?zhǔn)數(shù)的值放到基準(zhǔn)數(shù)左邊,7已經(jīng)小于8了,所以A = A + 1,將A指向20的位置)

哨兵B移動

之后A開始移動,發(fā)現(xiàn)本身位置20大于temp,那么不用繼續(xù)移動了,直接將20賦值給B所在位置,B向前移動一位。(同理)


哨兵A移動

第一次移動的一定是B哨兵而不是哨兵A,讀者可以先自己思考為什么這樣做,后面會給出答案。

移動到下圖的時候注意,此時應(yīng)該是B繼續(xù)向前搜索小于temp的值。


判斷A是否小于B

結(jié)果發(fā)現(xiàn),當(dāng)B移動到A位置時,發(fā)現(xiàn)也沒有找到小于temp的數(shù),這時就需要把temp這個基準(zhǔn)數(shù)插入到這個位置,結(jié)束一輪尋找。


插入基準(zhǔn)數(shù)

至此我們發(fā)現(xiàn),8左邊的數(shù)都小于8,右邊的數(shù)都大于8,這就完成了一次操作。

之后采用分治法,將8左邊的序列當(dāng)作一個數(shù)組,右邊的序列當(dāng)做一個數(shù)組,對兩個數(shù)組都進(jìn)行上面的操作(也就是重新傳入排序方法中,進(jìn)行遞歸調(diào)用)。

總結(jié)

  • 主要的判斷條件是A是否小于B,如果小于B就結(jié)束尋找將基準(zhǔn)數(shù)插入。
  • 為什么一定要從哨兵B先開始呢?其實(shí)自己實(shí)驗(yàn)一下就能知道為什么。

首先移動哨兵A,找到大于temp的值,也就是20,之后將20賦值給B的所在位置。
哨兵A移動

這里如果賦值了的話,那么15就變成20,15這個數(shù)就丟失了,你可能會想,我可以拿一個數(shù)先把15記錄下來呀,這樣做可以,我們假設(shè)用temp1記錄下15,之后繼續(xù)向下走,我們走到最后,如下圖。


最后

將基準(zhǔn)數(shù)8加入到arr[3]這個位置。那么temp1該如何處理呢,賦值到arr[0]位置嗎,如果這樣做,那8的左邊就出現(xiàn)了一個大于8的數(shù)字,違反了快速排序的條件。

全部代碼如下

/**
 * Created by ShouJingGuo on 2018/3/14.
 * 快速排序
 */
public class QuickSort<T> {
    private Comparator<T> comparator;

    QuickSort(Comparator<T> comparator){
        if(comparator == null){
            throw new NullPointerException("比較器不能為null");
        }
        this.comparator = comparator;
    }

    public void quickSort(T[] arr){
        int i = 0, j = arr.length - 1;
        quickSort(arr, i, j);
    }

    private void quickSort(T[] arr, int left, int right){
        if(left < right) {
            int i = left, j = right;
            T temp = arr[left];
            while (i < j) {
                while ((i < j) && (comparator.compare(temp, arr[j]) < 0)) {
                    j--;
                }
                if (i < j) {
                    arr[i++] = arr[j];
                }

                while ((i < j) && (comparator.compare(temp, arr[i]) > 0)) {
                    i++;
                }
                if (i < j) {
                    arr[j--] = arr[i];
                }
            }
            arr[i] = temp;
            quickSort(arr, left, i - 1);
            quickSort(arr, i + 1, right);
        }
    }

    public static void main(String[] args) {
        Integer arr[] = {10,50,24,11,68,20,41,0,24,25,4,7,94,15,5,44,66};
        QuickSort<Integer> quickSort = new QuickSort<>(new IntegerComparator());
        quickSort.quickSort(arr);
        System.out.println(Arrays.toString(arr));
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概述 排序有內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部...
    蟻前閱讀 5,301評論 0 52
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 將一個記錄插入到已排序好...
    依依玖玥閱讀 1,352評論 0 2
  • 冒泡排序 冒泡排序相對來說是較為簡單的一種排序,它的思想就是在每一次循環(huán)中比較相鄰的兩個數(shù),通過交換的方式,將最小...
    陌上疏影涼閱讀 644評論 0 3
  • 我需要領(lǐng)導(dǎo)者 別談奴隸不奴隸 我想要一個私有領(lǐng)導(dǎo)者 他占有我的情感 引導(dǎo)我的理智 我的意見在他面前暴露無遺,不堪一...
    寂寞冷少女閱讀 154評論 2 0
  • 前段時間,一個公益廣告用短短的幾分鐘,講述一個女孩在理發(fā)店不斷要求將頭發(fā)剪短的故事。當(dāng)及腰的長發(fā)剪成齊耳的短發(fā)時,...
    孤島的魚貓閱讀 854評論 0 5

友情鏈接更多精彩內(nèi)容