快排算法分析及圖解

分析

快排相當於在數組最左邊和數組最右邊定義兩個指針,將數組第一個元素定義爲key。

左指針負責將定位到的<key的元素全部丟到右邊,右指針負責將定位到的<=key的元素全部丟到左邊。

這樣一來,當循環結束後,將key值和兩個指針重疊的數值進行交換後,所有左邊的元素都<=key,而所有右邊的元素都>key。然後再重複以上做法,將key左邊的數組進行同樣的算法排序,右邊也一樣。

 

示例流程

這裏我們以{1,2,4,5,7,4,5,3,0}爲例進行分析。首先對{1,2,4,5,7,4,5,3,0}進行排序:

1.一開始i指向a[0],j指向a[a.length-1],key=a[0]

  • 當(a[j] > key && i < j) j--,即左移指針;

  • 當(a[i] <= key && i < j) i++,即右移指針;

  • 當i < j時,交換a[i]和a[j]位置;

  • 當i = j,觸發條件直接跳出while循環,並進行key值調整。

key

1 2 4 5 7 4 5 3 0

i                        j

第一次while循環(最外圈的while循環):

1 2 4 5 7 4 5 3 0

    i                    j

當i < j時,交換a[i]和a[j]位置:

1 0 4 5 7 4 5 3 2

    i                    j

 

第二次while循環:

key

1 0 4 5 7 4 5 3 2

   i                     j

1 0 4 5 7 4 5 3 2

   i

   j

i = j,觸發條件直接跳出while循環,進行key值調整:

0 1 4 5 7 4 5 3 2

   i

   j

 key

這樣一來,key左邊的都是小於key的,而key右邊的都是大於key的。

再進行左邊{0}和右邊{4,5,7,4,5,3,2}兩個數字的快排。流程如上。

 

2.對左邊數組{0}排序,i,j皆爲指針。

key

0

i

j

i = j,觸發條件直接跳出while循環,進行key值調整。因爲 i=j,所以交換後0還是0

 

3.對左邊數組{4,5,7,4,5,3,2}排序,i,j皆爲指針。

  • 當(a[j] > key && i < j) j--,即左移指針;

  • 當(a[i] <= key && i < j) i++,即右移指針;

  • 當i < j時,交換a[i]和a[j]位置;

  • 當i = j,觸發條件直接跳出while循環,並進行key值調整。

 

key

4 5 7 4 5 3 2

i                  j

第一次while循環:

4 5 7 4 5 3 2

   i               j

i < j時,交換a[i]和a[j]位置:

4 2 7 4 5 3 5

   i               j

4 2 7 4 5 3 5

      i         j

i < j時,交換a[i]和a[j]位置:

4 2 3 4 5 7 5

      i         j

4 2 3 4 5 7 5

         j

         i

當i = j,觸發條件直接跳出while循環,並進行key值調整。

現在4左邊的數字都<=4,4右邊的都>4,分爲了{4,2,3}和{5,7,5}兩個數組,對左右進行分別採用上面方法一樣遞歸排序即可。下面省略了分析流程。

 

代碼:

package com.quicksort;
 
import java.util.Arrays;
 
public class QuickSort {
    public static void main(String[] args) {
        int[] a = {1, 2, 4, 5, 7, 4, 5 ,3 ,9 ,0};
        System.out.println(Arrays.toString(a));
        quickSort(a);
        System.out.println(Arrays.toString(a));
    }
 
    public static void quickSort(int[] a) {
        if(a.length>0) {
            quickSort(a, 0 , a.length-1);
        }
    }
 
    private static void quickSort(int[] a, int low, int high) {
        //1,找到遞歸算法的出口
        if( low > high) {
            return;
        }
        //2, 存
        int i = low;
        int j = high;
        //3,key
        int key = a[ low ];
        //4,完成一趟排序
        while( i< j) {
            //4.1 ,從右往左找到第一個小於key的數
            while(i<j && a[j] > key){
                j--;
            }
            // 4.2 從左往右找到第一個大於key的數
            while( i<j && a[i] <= key) {
                i++;
            }
            //4.3 交換
            if(i<j) {
                int p = a[i];
                a[i] = a[j];
                a[j] = p;
            }
        }
        // 4.4,調整key的位置
        int p = a[i];
        a[i] = a[low];
        a[low] = p;
        //5, 對key左邊的數快排
        quickSort(a, low, i-1 );
        //6, 對key右邊的數快排
        quickSort(a, i+1, high);
    }
}

 

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