1. 程式人生 > >排序(四)之快速排序

排序(四)之快速排序

快速排序法

快速排序法相交之前的三種排序法來講,是一種執行速度較快的排序演算法,也是一種大家經常使用的排序演算法。 快速排序法使用一種分治的思想,將待排陣列切分成兩個子陣列,將兩個子陣列進行獨自的排序。

與歸併排序的區別

快速排序法與歸併排序不同,歸併排序是將兩個有序的子陣列分別排序,然後將兩個子陣列歸併後形成一個有序的陣列。而快速排序法則是將子陣列分別排序後直接就形成了一個有序的陣列。還有一個區別是歸併排序法是將待排陣列等分成兩份,而快速排序的切分位置取決於陣列本身。

程式碼

上面的敘述可能有一些抽象,下面列出程式碼,分析程式碼過後應該會更容易理解。 程式碼是用遞迴的方式實現的快速排序法,將陣列的第一個元素作為切分元素。 切分函式
public int partition(int a[] , int lo , int hi){

int i = lo;
int j = hi+1;
int v = a[lo];   //切分元素



while(true){

   while(less(a[++i],v))
      if(i == hi)
        break;

   while(less(v,a[--j]))
      if(j == lo)
        break;

   if(i >= j)
        break;

   exchange(a , j , i);

}

  exchange(a , lo , j );
   return j;
}


排序函式
protected void sort(int[] a, int lo, int hi) {
// TODO Auto-generated method stub

   if(hi <= lo) 
     return;

   int j = partition(a , lo , hi);
   sort(a , lo , j-1);
   sort(a , j+1 , hi);
}



因為使用遞迴所以程式碼量看上去很少,但是遞迴也相對於來說比較容易出錯。

關於時間複雜度

快速排序的最好情況是每次都能講陣列平均分成兩部分,時間複雜度約為N*lgN;最壞的情況是每次切分後有一個數組是為空,這是比較次數就是N+(N-1)+(N-2)+....+1 = (N+1)N/2. 快速排序法的平均時間複雜度約為N*lgN.

空間複雜度

遞迴演算法每次要儲存返回的資訊,需要附加額外的堆疊空間。快速排序法空間複雜度約為S(lgn).

穩定性

由於在快速排序中相同元素的相對位置會發生改變,所以快速排序法是不穩定的。