1. 快速排序:
快速排序是C.R.A.Hoare於1962年提出的一種劃分交換排序。它採用了一種分治的策略,通常稱其爲分治法(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 );
}