快速排序的深入理解

package com.joker.counts;

public class FastSort {
    /**
     * 快速排序
     * 原理,總體思路爲 分而治之(遞歸)
     * 具體操作:選中一個元素爲基數,以這個基數爲參照,和每個元素相比較,通過交換位置,將比該基數大的元素放在數組尾部,比該基數小的元素放在數組頭部。當已這個基數重新排序出來之後,
     * 數組分爲三個部分,[小於基數數組][基數][大於基數數據]。這時,分而治之,小於基數數組,大於基數數組分別再遞歸調用,即可完成排序。
     * @param counts
     * @param start
     * @param end
     */
    public static void sort(int[] counts,int start,int end){
        int left = start;
        int right = end;
        //選取基數
        int base = counts[start];
        //當left==right時,說明遍歷完了,也就是完成[小於基數數組][基數][大於基數數據]。這是第一次遍歷
        //重點:交換位置:
        //不管是從前往後查找還是從後往前查找,需要交換位置的元素爲本次查找到的數據和上一次查找到的數據,如果沒有上一次(第一次循環,則上一次爲選取的基數位置。)
        while(right>left){
            //此處爲什麼是選取了數組第一個元素爲基數,要從數組最後一個元素往前開始遍歷?
            //這和算法無關,只是爲了編程方便,因爲找到的元素和基數元素交換位置,
            //如果選取了第一個元素爲基數,而從第一個開始遍歷,即需要比較left和left++之後的left的值,無法編寫。而從數組尾部開始遍歷,則比較方便。
            //同理如果選取數組尾部的元素爲基數,則從第一個元素開始遍歷方便很多。
            while(right>left&&counts[right]>=base)
            right--;
            //找到了目標元素
            if(counts[right]<base){
                int temp = counts[right];
                counts[right] = counts[left];
                counts[left] = temp;
            }
            //找到了目標元素
            while(right>left&&counts[left]<=base)
                left++;
            if(counts[left]>base){
                int temp = counts[right];
                counts[right] = counts[left];
                counts[left] = temp;
            }
        }
        //left>start 說明從前往後看,基數位置發生了變化,[小於基數數組]那麼以基數爲分割點,從新遞歸排序。
        if(left>start) sort(counts,0,left-1);
        //end>right 說明從後往前看,基數位置發生了變化,[大於基數數組]那麼以基數爲分割點,從新遞歸排序。
        if(end>right) sort(counts,right+1,end);
            
    }
    public static void main(String[] args) {
        int[] counts = new int[] { 3, 2, 5, 6, 2, 1, 7, 3 };
        sort(counts, 0, counts.length-1);
        for (int i = 0; i < counts.length; i++) {
            System.out.println(counts[i]);
        }

    }
}
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章