1. 程式人生 > >看圖說話排序演算法之快速排序

看圖說話排序演算法之快速排序

  排序演算法(二)

本文著重介紹快速排序演算法(quick sort),快速排序和氣泡排序一樣是交換排序的一種,快速排序演算法可以看成是對氣泡排序演算法的改進演算法,其平均時間複雜度在nlog(n),基本上是已知的排序演算法中速度最快的一種。

氣泡排序的核心思想是通過一次冒泡交換將最大的元素置換到末尾,通過N-1次這樣的冒泡交換,完成對待排序陣列的排序。

快速排序的核心思想是通過一個partition(分割)操作,將陣列的某一個元素放置到正確的排序位置,接著遞迴對該元素的左側和右側分別進行partition操作,直到所有的元素都放到正確的位置,這樣排序就結束了。

下面通過一個圖例的方式來介紹對待排序陣列的一次partition操作。假設待排序陣列int []A = new int[]{5,1,4,7,9,3,2,5}。

一丶快速排序原理

1.隨便選取一個元素(後文簡稱特定元素),這裡選取第一個元素5,目的是將元素5放置到正確的排序位置,讓元素5左側的元素都小於或等於5,右側的元素都大於5。

2.在partition操作中,維護三個重要成員,left指標指向區間的第一個元素,right指標指向區間的最後一個元素,以及對選中元素額備份。


3.移動right指標,right=right-1,一直到A[right]<=5,停止移動移動left指標,left = left+1,一直到A[left]>5停止移動。

 

4.left指標移動和right指標移動結束後,交換left指標和right指標指向的內容。


5.繼續重複步驟2,3,4



6.繼續重複步驟2,3,4發現left=right,兩個指標相遇了,那麼結束本次partition操作,讓 left和right共同指向的元素去覆蓋選中的元素5。



7.將備份的元素5覆蓋left和right共同指向的元素。


8.執行完步驟7之後,一次的partion操作就結束了,將陣列分割成的兩個部分,在指定元素5的左側,所有的元素都小於或等於5,在指定元素的右側所有的元素都大於5。對左側的陣列{3,1,4,5,2}和右側陣列{9,7}遞迴partition操作。遞迴執行partition函式後,快速排序就完成了,陣列也由無序變為了有序的狀態了。

二丶快速排序的細節分析

(1)在一次partition操作中,對特定元素的指定一般都取待排序區間中的第一個元素。

(2)left指標和right指標的移動順序是存在區別的,必須先移動right指標,後移動left指標。試想當left和right指標相遇的時候,若先移動right指標,可以保證最後left和right指向的元素是嚴格小於或等於被指定元素的。這樣在執行步驟7和步驟8之後,可以完全的保證被指定元素放置在合適的位置——左側的所有元素小於自身,右側的所有元素大於自身。

(3)快速排序的每一次partition操作,必須輸入兩個引數——start和end。start代表待排序區間的開始位置,end代表待排序區間的結束位置。

(4)每一次partition操作,必須返回特定元素分割後的位置,用作下一次partition操作的依據。

(5)每次partition操作,如果start>end.則不執行partition流程。

   三丶java程式碼實現

  public static void quickSort(int [] num,intstart,int end){
      if(start>end)
        return ;
      int mid = partition(num,start,end);
     
      quickSort(num,start,mid-1);
 
      quickSort(num,mid+1,end);
   }
   public static int  partition(int[] num,int start,int end){
      int copy = num[start];
      int left = start;
      int right = end;
      while(left<right){
        while(left<right&&num[right]>copy){
           right = right -1;
        }
        while(left<right&&num[left]<=copy){
           left++;
        }
        int temp = num[left];
        num[left] = num[right];
        num[right] =temp;
      }
      num[start] = num[left];
      num[left] = copy;
     
      return left;
   }