1. 程式人生 > >指標交換法的快速排序不會實現怎麼辦?

指標交換法的快速排序不會實現怎麼辦?

我們先來了解一下什麼是指標交換法的快速排序。

在一個數組裡任意選擇一個數作為支點,方便起見選取第一個數為支點。把所有比支點小的數都放在支點的左側,而所有比支點大的數都放在支點的右側,這樣一個數組就分成了三個部分:

【比支點小的部分】 【支點】 【比支點大的部分】

然後我們繼續對支點兩邊凌亂的陣列呼叫該方法,直到陣列只有一個數,即支點兩側無數為止。

你可能會說,我知道這樣可我還是不會敲程式碼

別急咱一步一步慢慢來,我們先分析單次的執行

  1. 定義一個支點pivot儲存著第一個元素的值
  2. 定義一個索引i指向第一個數往後遍歷找到比支點大的值
  3. 定義一個索引j指向最後一個數往前遍歷找到比支點小的值
  4. 重複步驟2 3,直到i,j相遇

圖示如下:

在這裡插入圖片描述 i開始找比pivot大的數,就開始找比pivot小的數,找到後交換兩數 在這裡插入圖片描述

下來就出了一點問題,我們是先移動i呢,還是先移動j呢。其實很簡單因為最後要使pivot與arr[i]進行交換所以那就移動j,i保持不動。之後我們就得到了如下結果 在這裡插入圖片描述 這個例子可能對先移動誰不夠鮮明,我們試想一下下面這種情況。 升序排列的陣列j連一次移動的機會都沒有,便會得到如下結果: 在這裡插入圖片描述 然後1跟6再交換一下emmm很顯然做不到pivot的左邊比pivot小在這裡插入圖片描述 圖也嗶嗶了半天了,上程式碼吧

 public static void  quickSort(int[] arr,int left,int right){
     int i = left;//向右索引
     int j = right;//向左索引
     int temp;
     if(right<left){return;}
     int pivot = arr[left];//選取第一個數為支點
   while(i<j){
         while(i<j&&arr[j]>=pivot){//獲取比支點小的元素下標
              j--;
         }
         while(i<j&&arr[i]<=pivot){//獲取比支點大的元素下標
             i++;
         }
         //把兩個數交換
         temp = arr[i];
         arr[i] = arr[j];
         arr[j] = temp;
    }
         arr[left] = arr[i];
         arr[i] = pivot;
        //現在陣列被分為了三個部分
        // 【比支點小的部分】【支點arr[i]】【比支點大的部分】
        quickSort(arr,left,i-1);//分別對兩側進行同樣操作即可
        quickSort(arr,i+1,right);
        }
}

然後我們發現這個引數實在好長啊,我們要給arr排序還得這麼寫 quickSort(arr,0,arr.length-1)。這種重複的無意義的工作就交給計算機去做吧,程式設計師該做的就應該是偷懶。我們把它再封裝到一個方法裡。

 public static void quickSort(int arr[]){
        quickSort(arr,0,arr.length-1);
 }

這樣看起來是不是就清爽了很多~