排序

思考:堆排为什么比快排慢?:http://mindhacks.cn/2008/06/13/why-is-quicksort-so-quick/

总结各种排序算法的经典实现:

#include<stdio.h>
#define MAXV 1E9
/*
** N是正整数
** 讨论从小到大
** 基于排序的比较
** 只讨论内部排序
** 稳定性:任意两个相等的数据排序前后相对位置不发生变化
** 没有一种排序是任何情况下都表现最好的
** 逆序对:对于i<j,A[i] > A[j]
** 任意N个不同元素组成的序列平均具有 N(N-1)/4
*/
void PercDown( ElementType A[], int p, int N )
{
    int Parent, Child;
    ElementType X;

    X = A[p]; /* 取出根结点存放的值 */
    for( Parent=p; (Parent*2+1)<N; Parent=Child ) {
        Child = Parent * 2 + 1;
        if( (Child!=N-1) && (A[Child]<A[Child+1]) )
            Child++;  /* Child指向左右子结点的较大者 */
        if( X >= A[Child] ) break; /* 找到了合适位置 */
        else  /* 下滤X */
            A[Parent] = A[Child];
    }
    A[Parent] = X;
}
int ScanForMin(A,i,N-1){
    int minnum = MAXV;
    int minposition = -1;
    for(i; i <= N-1; i++){
        if(A[i] < res){
            res = A[i];
            minposition = i;
        }
    }
    return minposition;
}

void Bubble_Sort( ElementType A[], int N){
    for(int P = N-1; P>=0; P--){
        int flag = 0;
        for( int i = 0; i < P; i++){
            if( A[i] > A[i+1]) {
                Swap(&A[i], &A[i+1]);
                flag = 1;
            }
        }
        if( flag == 0) break;
    }
} // best:T = O(N); worse:T = O(N^2); 稳定。

void Insertion_Sort( ElementType A[], int N){
    for(int P = 1; P < N; P++){
        int Tmp = A[P];
        for(int i = P; i > 0 && A[i-1] > Tmp; i--){
            A[i] = A[i-1];
        }
        A[i] = Tmp;
    }
} // best:T = O(N); worse:T = O(N^2); 稳定。

/* 逆序对:对于i<j,A[i] > A[j]*/
/* 任意N个不同元素组成的序列平均具有 N(N-1)/4 */

void Shell_Sort(ElementType A[], int N){
    for( int D = N/2; D > 0; D/=2){
        for(int P = D;P < N; P++){
            int Tmp = A[P];
            for(int i = P; i >= D && A[i-D] > Tmp; i -= D){
                A[i] = A[i-D];
            }
            A[i] = Tmp;
        }
    }



}  //Sedgewick 增量序列可以加速;不稳定。


void Selection_Sort ( ElementType A[]; int N){
    for(int i = 0; i < N; i++){
        int MinPosition = ScanForMin(A,i,N-1);
        Swap( &A[i],&A[MinPosition]);
    }
}// T = O(N^2); 可用堆加速。


void Heap_Sort ( ElementType A[]; int N){
    for(int i = N/2; i >= 0; i--){
        PercDown(A,i,N);
    }
    for(int i = N-1; i > 0; i--){
        Swap(&A[0],&A[i]);
        PercDown(A,0,i);
    }
} // 适合数据量大,适合部分排序,找出最大或最小的N个数


void Merge(ElementType A[], ElempentType TmpA[],int L, int R,int RightEnd){
    int leftEnd = R - 1;
    int Tmp = L;  //存放结果的数组初始位置
    NumElements = RightEnd - L + 1;
    while(L<=LeftEnd && R <= RightEnd){
        if(A[L] <= A[R]) TmpA[Tmp++] = A[L++];
        else TmpA[Tmp++] = A[R++];
    }
    while( L <= LeftEnd ){
        TmpA[Tmp++] = A[L++];
    }
    while( R <= RightEnd ){
        TmpA[Tmp++] = A[R++];
    }
    for( i = 0; i < NumElements; i++, RightEnd -- ){
        A[RightEnd] = TmpA[RightEnd];
    }
}
void Msort( ElementType A[], ElementType TmpA[], int L, int RightEnd )
{
     int Center;

     if ( L < RightEnd ) {
          Center = (L+RightEnd) / 2;
          Msort( A, TmpA, L, Center );              /* 递归解决左边 */
          Msort( A, TmpA, Center+1, RightEnd );     /* 递归解决右边 */
          Merge( A, TmpA, L, Center+1, RightEnd );  /* 合并两段有序序列 */
     }
}  //T(N) = O(NlogN);稳定。
void Merge_Sort1( ElementType A[], int N )
{ /* 归并排序 */
     ElementType *TmpA;
     TmpA = (ElementType *)malloc(N*sizeof(ElementType));

     if ( TmpA != NULL ) {
          Msort( A, TmpA, 0, N-1 );
          free( TmpA );
     }
     else printf( "空间不足" );
} //稳定;需要额外空间;一般用于外排序

void Merge_pass( ElementType A[], ElementType TmpA[], int N, int length )
{ /* 两两归并相邻有序子列 */
     int i, j;

     for ( i=0; i <= N-2*length; i += 2*length )
         Merge( A, TmpA, i, i+length, i+2*length-1 );  //可优化,merge可不必执行最后一步。
     if ( i+length < N ) /* 归并最后2个子列*/
         Merge( A, TmpA, i, i+length, N-1);
     else /* 最后只剩1个子列*/
         for ( j = i; j < N; j++ ) TmpA[j] = A[j];
}

void Merge_Sort2( ElementType A[], int N )   //非递归merge
{
     int length;
     ElementType *TmpA;

     length = 1; /* 初始化子序列长度*/
     TmpA = malloc( N * sizeof( ElementType ) );
     if ( TmpA != NULL ) {
          while( length < N ) {
              Merge_pass( A, TmpA, N, length );
              length *= 2;
              Merge_pass( TmpA, A, N, length );
              length *= 2;
          }
          free( TmpA );
     }
     else printf( "空间不足" );
}

 

posted @ 2018-06-04 22:56  又啦  阅读(108)  评论(0编辑  收藏  举报