zoukankan      html  css  js  c++  java
  • 数据结构与算法- 经典排序算法实现

    一、排序算法

    冒泡、选择、插入、希尔、快速、归并、堆和计数排序(省略了基数排序和桶排序)

    以及C语言自带的排序函数

    #include <stdio.h>
    #include <stdlib.h>
    typedef int ElementType;
    
    void Swap(ElementType *a, ElementType *b)
    {
         ElementType t = *a;
         *a = *b; 
         *b = t;
    }
    
    void Bubble_sort(ElementType A[], int N)
    {
        int i, j, flag;
        for ( i = N; i > 0; i-- ) {        
            flag = 0;  
            for ( j = 1; j < i; j++ ) {
                // 冒泡排序将更大的值和更小值进行交换        
                if ( A[j-1] > A[j] ) {
                    Swap( &A[j-1], &A[j] );
                    flag = 1;       // exchange occur 
                }
            }
            if ( flag == 0 ) break; // 若全程无交换,表明已排好序 
        }
    }
    
    void Select_sort(ElementType A[], int N)
    {   
        int i, j, index;         // 每一趟扫描选择最大(最小)值与初始位置进行交换 
        ElementType Max;
        for ( i = N; i > 1; i-- ) {    
            Max = A[0];          // i : from N to 2 
            index = 0;           // 初始化索引,第一位也可能为最大元素 
            for ( j = 1; j < i; j++ ) { 
                if ( A[j] > Max ) {
                    Max = A[j];  // 在当前循环内找到一个最大的元素 
                    index = j;
                }
            }
            Swap(&A[i-1], &A[index]);        
        }
    }
    
    void Insert_sort(ElementType A[], int N)
    {
        int i, j;
        ElementType tmp;    
        for ( i = 1; i < N; i++ ) {
            tmp = A[i];
            // 每一趟反向遍历,将大于tmp的元素向后移动(等价于将tmp前插到合适的位置) 
            for ( j = i; j > 0 && A[j-1] > tmp; j-- ) {
                A[j] = A[j-1];
            } 
            A[j] = tmp; 
        }
    }
    
    void Shell_sort(ElementType A[], int N) 
    {
        int i, j; 
        int increment;
        ElementType Tmp;  // increment sort 
        for ( increment=N/2; increment>0; increment/=2 ) {    
            // insertion sort 
            for ( i=increment; i<N; i++ ) {
                Tmp = A[i];
                for ( j=i; (j>=increment)&&(A[j-increment]>Tmp); j-=increment ) {
                    A[j] = A[j-increment];
                } 
                A[j] = Tmp;
            }    
        }    
    }
    
    
    // Qucik Sort 
    #define Cutoff 20
    ElementType Median3(ElementType A[], int Left, int Right)
    {   // return median of Left, Center, Right 
        int Center = ( Left + Right) / 2;
        
        if( A[Left] > A[Center] )
            Swap( &A[Left], &A[Center] );    
        if( A[Left] > A[Right] )
            Swap( &A[Left], &A[Right] );
        if( A[Center] > A[Right] )
            Swap( &A[Center], &A[Right] );
        // A[Left] <= A[Cetner] <= A[Right]     
        Swap( &A[Center], &A[Right-1] );
        // 将pivot隐藏在右边作为哨兵,并返回它 
        return A[Right-1];
    }
    
    void Q_sort(ElementType A[], int Left, int Right)
    {
        int i, j;  // pointer 
        ElementType pivot; 
        
        if ( Left + Cutoff <= Right ) {  
             // large range Cutoff <= Right - Left = N - 1 
            pivot = Median3( A, Left, Right );
            i = Left;
            j = Right - 1;
            for ( ; ; ) {
                while( A[++i] < pivot );  // find a num large than pivot from left
                while( A[--j] > pivot );  // find a num less than pivot from right
                if ( i < j ) { 
                    Swap( &A[i], &A[j] ); // pointer in range 
                }
                else 
                    break;
            }
            Swap( &A[i], &A[Right - 1] ); // restroe pivot
            Q_sort( A, Left, i - 1 );     // from pivot to divid sort 
            Q_sort( A, i + 1, Right );
        } else
            Insert_sort( A, Right - Left + 1 );
            
    }
    
    void Quick_sort(ElementType A[], int N)
    {
        Q_sort( A, 0, N-1 ); // 递归式地划分,将小于pivot的划到左边,大于pivot划到右边 
    } 
    
    
    // Merge sort需要额外的内存空间 
    void Merge(ElementType A[], ElementType TmpArray[], int Lpos, int Rpos, int Rightend)
    {
        int i, Leftend, NumElements, Tmp;
        
        Leftend = Rpos - 1;
        Tmp = Lpos;
        NumElements = Rightend - Lpos + 1;
        // main loop     
        while ( Lpos <=Leftend && Rpos <= Rightend ) {
            if ( A[Lpos] <= A[Rpos] )
                TmpArray[Tmp++] = A[Lpos++];
            else
                TmpArray[Tmp++] = A[Rpos++];                
        }
        
        while ( Lpos <=Leftend ) 
            TmpArray[Tmp++] = A[Lpos++];
        while ( Rpos <= Rightend ) 
            TmpArray[Tmp++] = A[Rpos++];
            
        for ( i = 0; i < NumElements; i++, Rightend-- ) {  
            A[Rightend] = TmpArray[Rightend];  // copy array back 
        }
    }
    
    void MSort(ElementType A[], ElementType TmpArray[], int Left, int Right)
    {
        int Center;
         if ( Left < Right ) {
             Center = ( Left + Right ) / 2;
             MSort( A, TmpArray, Left, Center );
             MSort( A, TmpArray, Center + 1, Right );
             Merge( A, TmpArray, Left, Center + 1, Right );
         }
    }
    
    void Merge_sort(ElementType A[], int N)
    {
        ElementType *TmpArray;
        TmpArray = malloc( N * sizeof( ElementType ) );
        if ( TmpArray != NULL ) {
            MSort( A, TmpArray, 0, N-1 );
            free(TmpArray);
        } else {
            printf("No space for tmp array!");
        }
    }
    
    
    /* 堆排序  这里只插入了N个元素 */
    void PercDown(ElementType A[], int p, int N)
    { 
        int Parent, Child;  // 将N个元素的数组中以A[p]为根的子堆调整为最大堆 
        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  
                A[Parent] = A[Child];  //下滤X 
        }
        A[Parent] = X;
    }
    
    void Heap_sort(ElementType A[], int N) 
    { 
         int i;
           
         for ( i = N/2 - 1; i >= 0; i-- ) // 建立最大堆 
             PercDown( A, i, N );
          
         for ( i = N - 1; i > 0; i-- ) {
             Swap(&A[0], &A[i]);          // 删除最大堆顶
             PercDown( A, 0, i);
         }
    }
    
    void Count_sort(ElementType A[], int N)
    {    
        int i, j, count;
        int size = 101;   //假设count size为100,对较小的数(如分数)进行排序
        ElementType B[size];
        
        for ( i = 0; i < size; i++ ) {
            B[i] = 0;
        }     
        for ( i = 0; i < N; i++ ) {
            B[ A[i] ]++;  // count the number
        } 
        count = 0;        // output, from 0 to N -1 in A[] 
        for ( i = 0; i < size; i++ ) {   
            // bucket not empty 
            if ( B[i] != 0 ) {  
                 // B[i] is equal to frequency of i 
                for ( j = 0; j < B[i]; j++, count++) {
                    A[count] = i;
                }
            }
        } 
    }
    
    int cmpfunc (const void * a, const void * b)
    {
        return ( *(int*)a - *(int*)b );
    }
    
    
    int main()
    {
        ElementType *A;
        int i, N, flag;    
        N = 1;
        printf("
    array length? if length < 0 then quit
    ");    
        while ( N >= 1 ) {
            scanf("%d", &N);    
            A = (ElementType*)malloc( N * sizeof(ElementType));
            printf("
    Array: "); 
            for ( i = 0; i < N; i++ ) {
                A[i] = ( rand() % 100 );
                printf("%d ", A[i]);
            }    
            
            printf("
    Choose sort:");
            printf("0:default  1:bubble  2:select  3:insert  4:shell
    ");
            printf("            5:quick    6:merge   7:heap    8:count
    ");    
            scanf("%d", &flag);
            switch( flag ) {
                case 0:  qsort(A, N, sizeof(ElementType), cmpfunc); break;    
                case 1:  Bubble_sort(A, N); break;    
                case 2:  Select_sort(A, N); break;    
                case 3:  Insert_sort(A, N); break;    
                case 4:  Shell_sort(A, N); break;    
                case 5:  Quick_sort(A, N); break;    
                case 6:  Merge_sort(A, N);    break;                                            
                case 7:  Heap_sort(A, N);    break;    
                case 8:  Count_sort(A, N);    break;        
                default: break;        
            }
            
            printf("
    Array after sort: ");    
            for ( i = 0; i < N; i++ )
                printf("%d ", A[i]);    
            printf("
    ");    
        } 
        
        return 0;
    }
  • 相关阅读:
    JavaScript-4.2函数,变量作用域---ShinePans
    2019-8-31-C#-简单读取文件
    2019-8-31-C#-简单读取文件
    2019-8-31-C#-大端小端转换
    2019-8-31-C#-大端小端转换
    2019-6-11-C#-标准性能测试
    2019-6-11-C#-标准性能测试
    2018-2-13-win10-uwp-右击选择-GridViewItem-
    2018-2-13-win10-uwp-右击选择-GridViewItem-
    2019-8-31-NuGet-如何设置图标
  • 原文地址:https://www.cnblogs.com/justLittleStar/p/13430686.html
Copyright © 2011-2022 走看看