兩種快速排序代碼實現

算法設計:兩種快速排序代碼實現

快速排序是一種高效且使用廣泛的排序算法,在很多語言的標準庫中自帶的排序都是快速排序,所以我們也有必要了解快排的原理以及其實現方法。

快排的大致思想

快速排序實現的重點在於數組的拆分,通常我們將數組的第一個元素定義爲比較元素,然後將數組中小於比較元素的數放到左邊,將大於比較元素的放到右邊,

這樣我們就將數組拆分成了左右兩部分:小於比較元素的數組;大於比較元素的數組。我們再對這兩個數組進行同樣的拆分,直到拆分到不能再拆分,數組就自然而然地以升序排列了。

img

不難看出,拆分算法是整個快速排序中的核心,快速排序擁有非常多的拆分方式,在本篇文章中我們介紹其中的兩種,我個人將它稱作:單指針遍歷法與雙指針遍歷法(在下文中用英文單詞split和partition稱呼)

split算法解析

split算法使用一個單向的指針來對數組進行遍歷,首先將數組首元素設置爲比較元素,然後將第二個開始的元素依次與比較元素比較,如果大於比較元素則跳過,如果小於比較元素,則將其與前面較大的元素進行交換,將數組中所有元素交換完畢後,再將比較元素放到中間位置。

img

split算法實現(java):

//快速排序split實現方法
public class T1 {
    public static void main(String args[])
    {
        int a[] = {5,7,1,6,4,8,3,2};
        quickSort(a, 0, a.length-1);
        for(int i=0;i<a.length;i++)
            System.out.print(a[i] + " ");
        System.out.println();
    }
    
    //交換方法
    public static void swap(int a[], int i, int j)
    {
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
    
    //劃分數組
    public static int split(int a[], int low, int high)
    {
        int i = low;    //i指向比較元素的期望位置
        int x = a[low];    //將該組的第一個元素作爲比較元素
        //從第二個元素開始,若當前元素大於比較元素,將其跳過
        for(int j = low+1; j <= high; j++)
            //若找到了小於比較元素的元素,將其與前面較大的元素進行交換
            if(a[j] <= x)
            {
                i++;
                if(i != j)
                    swap(a, i, j);
                
            }
        swap(a, i, low);     //將比較元素交換到正確的位置上
        return i;    //返回比較元素的位置
    }
    
    public static void quickSort(int a[], int low, int high)
    {
        if(low < high)
        {
            int i = split(a, low, high);    //劃分並獲取比較元素的位置
            quickSort(a, low, i-1);     //對比較元素左邊的數組進行排序
            quickSort(a, i+1, high);     //對比較元素右邊的數字進行排序
        }
    }
}

partition算法解析

partition算法使用頭尾兩個方向相反的指針進行遍歷,先將數組第一個元素設置爲比較元素,頭指針從左至右找到第一個大於比較元素的數,尾指針從右至左找到第一個小於比較元素的數,全部交換完畢後將比較元素放到中間位置。

img

partition算法(java):

//快速排序partition實現方法
public class T2 {
    public static void main(String args[])
    {
        int a[] = {5,7,1,6,4,8,3,2};
        quicksort(a, 0, a.length-1);
        for(int i=0;i<a.length;i++)
            System.out.print(a[i] + " ");
        System.out.println();
    }
    
    public static void swap(int a[], int i, int j)
    {
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
    
    //劃分數組
    public static int partition(int a[], int low, int high)
    {
        int x = a[low];    //將該數組第一個元素設置爲比較元素
        int i=low;
        int j=high;
        while(i < j)
        {
            while(i<j && a[j] >= x)
                j--;     //從右至左找到第一個小於比較元素的數
            while(i<j && a[i] <= x)
                i++;     //從左至右找到第一個大於比較元素的數
            /*需要注意的是,這裏的j--與i++的順序不可以調換!
             *如果調換了順序,i會走過頭,以至於將後面較大的元素交換到數組開頭*/
            
            //將大數與小數交換
            if(i!=j)
                swap(a, i, j);
        }
        swap(a, i, low);    //將比較元素交換到期望位置
        return i;     //返回比較元素的位置
    }
    
    public static void quicksort(int a[], int low, int high)
    {
        if(low < high)
        {
            int i = partition(a, low, high);    //劃分數組並獲取比較元素的位置
            quicksort(a, low, i-1);     //對比較元素左邊進行排序
            quicksort(a, i+1, high);     //對比較元素右邊進行排序
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章