基础问题[ 快速排序 ]、[ 归并排序 ]

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 );

}










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