基礎問題[ 快速排序 ]、[ 歸併排序 ]

1. 快速排序:

快速排序是C.R.A.Hoare1962年提出的一種劃分交換排序。它採用了一種分治的策略,通常稱其爲分治法(Divide-and-ConquerMethod)

該方法的基本思想是:

1.先從數列中取出一個數作爲基準數

2.分區過程,將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊

3.再對左右區間重複第二步,直到各區間只有一個數。

代碼如下:

typedef struct Item{
    int key;
    int value;
} * PtrItem, * PtrList;

void exch( Item &a, Item &b ){
    //交換a, b
}


// 每次交換樞軸值 和 需要交換的元素。
int partition( PtrList  a,  int i, int j ){
    int key = a[ i ].key;
    while( i < j ){
        while( i < j  && a[ j ].key >= key ) j --;
        //此時,a[i]>=key, a[j] < key.
        exch( a[i], a[j] );  
        while( i < j && a[ i ].key < key) i ++;
        //此時, a[i] >= key, a[j] < key.
        exch( a[i], a[j] );
        // i == j 時,不影響.
    }
    return i;
}

// 樞軸值只需要最後放在需要的位置上.
int partition2( PtrList  a,  int i, int j ){
    Item pivot = a[ i ];
    int key = a[ i ].key;
    // 此時 a[i] 所在的位置可以用來存放大於key元素。
    while( i < j ){
        while( i < j  && a[ j ].key >= key ) j --;
        //此時,a[i]位置爲空.
        a[ i ] = a[ j ];
        // 若 i < j , a[ i ] < key
        while( i < j && a[ i ].key < key) i ++;
        //此時, a[ j ]位置爲空.
       a[ j ] = a[ i ];      
    }
    // 退出的可能性只可能是 i == j 
    a[ i ] = pivot;
    return i;
}

在 partitona2中,在 a[ i ] = a[ j ] 之後,不用進行 i ++ 的操作,因爲此時 a[i].key( 原來a[j].key ) 一定會小於 key。

quick_sort( a, i, j ){

    if ( i >= j ) return;

    pivotloc = partition2( a, i, j );

    quick_sort( a, i, pivotloc - 1);

    quick_sotrt(a, pivotloc+1, j);

}

   

2. 歸併排序的遞歸 和 非遞歸算法

非遞歸算法:

依次將數組A中長度爲1, 2, 4, 8, ..., 2^m( 2^<length(A) )的相鄰兩段進行歸併。第一次歸併保證長度爲2的子數組是有序的,第二次保證長度爲4的子數組是有序的...。僞代碼如下(數組下標從0開始):

for( step = 1; step < A.length; step += step ){

    for( indx = 0;  (A.length-1) - indx +1 > step ; indx += 2*step ){   //退出條件是: indx 到 A.length-1中不止一個step元素. 

              merge( A, indx, indx+step-1, min( indx+2*step-1, A.length-1) );   //合併相鄰兩段

     }

}

merge( A, i, m, j ): 合併A [i ... m] 、A[m+1 ... j] 到 A[i ... j]。

遞歸算法:

MergeSort( A, int s, int t ){

    if( s==t ) return;

    m = (s+t)/2;

    MergeSort(A, s, m); MergeSrot(A, m+1, t);

    merge( A, s, m, t );

}










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