• 排序


    思考:堆排为什么比快排慢?: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( "空间不足" );
    }
  • 相关阅读:
    程序员最艰难的十大任务
    ssh(安全外壳协议)
    数据库备份 计划任务
    计划任务 crontab
    数据库设计二
    mysql存储过程详解[转]
    Java开发必装的IntelliJ IDEA插件
    SQLYog快捷键大全
    HTTP深入浅出 http请求
    浏览器HTTP请求分析
  • 原文地址:https://www.cnblogs.com/jinjin-2018/p/9136437.html
Copyright © 2020-2023  润新知