• [数据结构与算法] : 排序


      1 /* This file contains a collection of sorting routines */
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include "fatal.h"
      5 
      6 typedef int ElementType;
      7 
      8 void Swap(ElementType *Lhs, ElementType *Rhs)
      9 {
     10     ElementType Tmp;
     11     Tmp = *Lhs;
     12     *Lhs = *Rhs;
     13     *Rhs = Tmp;
     14 }
     15 
     16 void PrintArray(ElementType A[], int N)
     17 {
     18     int i;
     19     for(i = 0; i < N; ++i)
     20         printf("%d ", A[i]);
     21     printf("
    ");
     22 }
     23 
     24 void InsertionSort(ElementType A[], int N)
     25 {
     26     int i, j;
     27     ElementType Tmp;
     28 
     29     for(i = 1; i < N; ++i)
     30     {
     31         Tmp = A[i];
     32         for(j = i; j >= 1 && A[j-1] > Tmp; --j)
     33             A[j] = A[j-1];
     34         A[j] = Tmp;
     35     }
     36 }
     37 
     38 void ShellSort(ElementType A[], int N)
     39 {
     40     int i, j, Increment;
     41     ElementType Tmp;
     42 
     43     for(Increment = N/2; Increment > 0; Increment /=2)
     44     {
     45         for(i = Increment; i < N; ++i)
     46         {
     47             Tmp = A[i];
     48             for(j = i; j >= Increment && A[j-Increment] > Tmp; j -= Increment)
     49                 A[j] = A[j-Increment];
     50             A[j] = Tmp;
     51         }
     52     }
     53 }
     54 
     55 // 简单选择排序
     56 void SelectSort(ElementType A[], int N)
     57 {
     58     int i, j;
     59     int MinIdx;
     60 
     61     for(i = 0; i < N-1; ++i) // N-1次即可完成排序
     62     {
     63         MinIdx = i;
     64         for(j = i+1; j < N; ++j) // 在[i+1, N)范围内查找最小值
     65         {
     66             if(A[j] < A[MinIdx])
     67                 MinIdx = j;
     68         }
     69         if(i != MinIdx)
     70             Swap(&A[i], &A[MinIdx]);
     71     }
     72 }
     73 
     74 // 简单选择排序的改进: 在查找最小值的同时,可以查找出最大值,
     75 // 最小值和第一个元素交换,最大值和最后一个元素交换。
     76 void SelectSortII(ElementType A[], int N)
     77 {
     78     int i, j;
     79     int MinIdx, MaxIdx;
     80 
     81     for(i = 0; i < N/2; ++i) // 一次排好最小值和最大值, 因此N/2次循环可以排好整个序列
     82     {
     83         MinIdx = i;
     84         MaxIdx = N-i-1;
     85         for(j = i; j < N-i; ++j) // 在[i, N-i)范围内查找最小值和最大值, 注意不能从i+1开始
     86         {
     87             if(A[j] < A[MinIdx])
     88                 MinIdx = j;
     89             if(A[j] > A[MaxIdx])
     90                 MaxIdx = j;
     91         }
     92 
     93         if(MinIdx != i)
     94             Swap(&A[MinIdx], &A[i]);
     95         if(MaxIdx != N-i-1)
     96             Swap(&A[MaxIdx], &A[N-i-1]);
     97     }
     98 }
     99 
    100 // 第6.3节讲的二叉堆左儿子为2*i, 右儿子为2*i+1, 下标为0的元素用于标记
    101 // 堆排序中不使用头节点, 因此左儿子为2*i+1, 右儿子为2*i+2
    102 #define LeftChild(i) ( 2 * (i) + 1 )
    103 
    104 void PercDown(ElementType A[], int i, int N)
    105 {
    106     int Child;
    107     ElementType Tmp;
    108 
    109     for(Tmp = A[i]; LeftChild(i) < N; i = Child)
    110     {
    111         Child = LeftChild(i);
    112         if(Child != N-1 && A[Child + 1] > A[Child])
    113             Child++;
    114 
    115         if(Tmp < A[Child])
    116             A[i] = A[Child];
    117         else
    118             break;
    119     }
    120     A[i] = Tmp;
    121 }
    122 
    123 void HeapSort(ElementType A[], int N)
    124 {
    125     int i;
    126 
    127     for(i = N/2; i >= 0; --i) /* BuildHeap */
    128         PercDown(A, i, N);
    129 
    130     for(i = N-1; i > 0; --i)  /* DeleteMax */
    131     {
    132         Swap(&A[0], &A[i]);
    133         PercDown(A, 0, i);
    134     }
    135 }
    136 
    137 // N个元素需要N-1趟才可以排好, i的取值为[0, N-1);
    138 // 每趟排序都会确定最后一个元素, 因此j的上界为N-i,
    139 // 考虑到循环内部使用了j+1, 因此上界应该为N-i-1,
    140 // 每趟比较从第0个元素开始, 下界为0
    141 void BubbleSort(ElementType A[], int N)
    142 {
    143     int i, j;
    144 
    145     for(i = 0; i < N-1; ++i)
    146     {
    147         for(j = 0; j < N-i-1; ++j)
    148         {
    149             if(A[j] > A[j+1])
    150                 Swap(&A[j], &A[j+1]);
    151         }
    152         PrintArray(A, 7);
    153     }
    154 }
    155 
    156 /* Lpos = start of left half, Rpos = start of right half */
    157 void Merge(ElementType A[], ElementType TmpArray[],
    158            int Lpos, int Rpos, int RightEnd)
    159 {
    160     int i, LeftEnd, NumElements, TmpPos;
    161 
    162     LeftEnd = Rpos - 1;
    163     TmpPos = Lpos;
    164     NumElements = RightEnd - Lpos + 1;
    165 
    166     /* main loop */
    167     while(Lpos <= LeftEnd && Rpos <= RightEnd)
    168         if(A[Lpos] < A[Rpos])
    169             TmpArray[TmpPos++] = A[Lpos++];
    170         else
    171             TmpArray[TmpPos++] = A[Rpos++];
    172     while(Lpos <= LeftEnd)  /* Copy rest of first half */
    173         TmpArray[TmpPos++] = A[Lpos++];
    174     while(Rpos <= RightEnd) /* Copy rest of second half */
    175         TmpArray[TmpPos++] = A[Rpos++];
    176 
    177     /* Copy TmpArray back */
    178     for(i = 0; i < NumElements; ++i, RightEnd--)
    179         A[RightEnd] = TmpArray[RightEnd];
    180 }
    181 
    182 void MSort(ElementType A[], ElementType TmpArray[], int Left, int Right)
    183 {
    184     int Center;
    185 
    186     if(Left < Right)
    187     {
    188         Center = (Left + Right) / 2;
    189         MSort(A, TmpArray, Left, Center);
    190         MSort(A, TmpArray, Center+1, Right);
    191         Merge(A, TmpArray, Left, Center+1, Right);
    192     }
    193 }
    194 
    195 // MergeSort为递归例程MSort的驱动程序
    196 void MergeSort(ElementType A[], int N)
    197 {
    198     ElementType *TmpArray;
    199 
    200     TmpArray = (ElementType *)malloc(N * sizeof(ElementType));
    201     if(TmpArray != NULL)
    202     {
    203         MSort(A, TmpArray, 0, N-1); // 注意是N-1
    204         free(TmpArray);
    205     }
    206     else
    207         FatalError("Out of space!");
    208 }
    209 
    210 /* Return median of Left, Center, and Right */
    211 /* Order these and hide the pivot */
    212 ElementType Median3(ElementType A[], int Left, int Right)
    213 {
    214     int Center = (Left + Right) / 2;
    215 
    216     if(A[Left] > A[Center])
    217         Swap(&A[Left], &A[Center]);
    218     if(A[Left] > A[Right])
    219         Swap(&A[Left], &A[Right]);
    220     if(A[Center] > A[Right])
    221         Swap(&A[Center], &A[Right]);
    222 
    223     /* Invariant: A[ Left ] <= A[ Center ] <= A[ Right ] */
    224 
    225     Swap(&A[Center], &A[Right-1]); /* Hide pivot */
    226     return A[Right-1];             /* Return pivot */
    227 }
    228 
    229 #define Cutoff (3)
    230 
    231 void Qsort(ElementType A[], int Left, int Right)
    232 {
    233     int i, j;
    234     ElementType Pivot;
    235 
    236     if(Left + Cutoff <= Right)
    237     {
    238         Pivot = Median3(A, Left, Right);
    239         i = Left;
    240         j = Right - 1;
    241         for( ; ; )
    242         {
    243             while(A[++i] < Pivot){}
    244             while(A[--j] > Pivot){}
    245             if(i < j)
    246                 Swap(&A[i], &A[j]);
    247             else
    248                 break;
    249         }
    250         Swap(&A[i], &A[Right-1]); /* Restore pivot */
    251 
    252         Qsort(A, Left, i - 1);
    253         Qsort(A, i + 1, Right);
    254     }
    255     else /* Do an insertion sort on the subarray */
    256         InsertionSort(A + Left, Right - Left + 1);
    257 }
    258 
    259 /*
    260 // 测试通过, 选取最后一个元素为枢纽元的排序方法
    261 void Qsort(ElementType A[], int Left, int Right)
    262 {
    263     int i, j;
    264     ElementType Pivot;
    265 
    266     if(Left < Right) // 这里用 < 或者 <=都可以
    267     {
    268         Pivot = A[Right]; // 选择最右边的元素为枢纽元
    269         i = Left-1, j = Right; // 注意这里i= Left - 1  !!!!
    270         for( ; ; )
    271         {
    272             while(A[++i] < Pivot){}
    273             while(A[--j] > Pivot){}
    274             if(i < j)
    275                 Swap(&A[i], &A[j]);
    276             else
    277                 break;
    278         }
    279         Swap(&A[i], &A[Right]);
    280 
    281         Qsort(A, Left, i - 1);
    282         Qsort(A, i + 1, Right);
    283     }
    284 }
    285 */
    286 
    287 void QuickSort(ElementType A[], int N)
    288 {
    289     Qsort(A, 0, N-1);
    290 }
    291 
    292 /* Places the kth smallest element in the kth position */
    293 /* Because arrays start at 0, this will be index k-1 */
    294 void Qselect(ElementType A[], int k, int Left, int Right)
    295 {
    296     int i, j;
    297     ElementType Pivot;
    298 
    299     if(Left + Cutoff <= Right)
    300     {
    301         Pivot = Median3(A, Left, Right);
    302         i = Left;
    303         j = Right - 1;
    304         for(; ;)
    305         {
    306             while(A[++i] < Pivot){}
    307             while(A[--j] > Pivot){}
    308             if(i < j)
    309                 Swap(&A[i], &A[j]);
    310             else
    311                 break;
    312         }
    313         Swap(&A[i], &A[Right-1]); /* Restore pivot */
    314 
    315         if(k <= i)
    316             Qselect(A, k, Left, i - 1);
    317         else
    318             Qselect(A, k, i + 1, Right);
    319     }
    320     else /* Do an insertion sort on the subarray */
    321         InsertionSort(A + Left, Right - Left + 1);
    322 }
    323 
    324 /* ROUTINES TO TEST THE SORTS */
    325 void Permute(ElementType A[], int N)
    326 {
    327     int i;
    328 
    329     for(i = 0; i < N; ++i)
    330         A[i] = i;
    331     for(i = 1; i < N; ++i)
    332         Swap(&A[i], &A[rand() % (i + 1)]);
    333 }
    334 
    335 void CheckSort(ElementType A[], int N)
    336 {
    337     int i;
    338 
    339     for(i = 0; i < N; ++i)
    340         if(A[i] != i)
    341             printf("Sort fails: %d
    ", i);
    342     printf("Check completed
    ");
    343 }
    344 
    345 void Copy(ElementType Lhs[], const ElementType Rhs[], int N)
    346 {
    347     int i;
    348     for(i = 0; i < N; ++i)
    349         Lhs[i] = Rhs[i];
    350 }
    351 
    352 #define MaxSize 7000
    353 int Arr1[MaxSize];
    354 int Arr2[MaxSize];
    355 
    356 int main()
    357 {
    358     int i;
    359     for(i = 0; i < 10; ++i)
    360     {
    361         Permute(Arr2, MaxSize); // 生成一个随机数组
    362 
    363         Copy(Arr1, Arr2, MaxSize);
    364         InsertionSort(Arr1, MaxSize);
    365         CheckSort(Arr1, MaxSize);
    366 
    367         Copy(Arr1, Arr2, MaxSize);
    368         ShellSort(Arr1, MaxSize);
    369         CheckSort(Arr1, MaxSize);
    370 
    371         Copy(Arr1, Arr2, MaxSize);
    372         HeapSort(Arr1, MaxSize);
    373         CheckSort(Arr1, MaxSize);
    374 
    375         Copy(Arr1, Arr2, MaxSize);
    376         MergeSort(Arr1, MaxSize);
    377         CheckSort(Arr1, MaxSize);
    378 
    379         Copy(Arr1, Arr2, MaxSize);
    380         QuickSort(Arr1, MaxSize);
    381         CheckSort(Arr1, MaxSize);
    382 
    383         Copy(Arr1, Arr2, MaxSize);
    384         Qselect(Arr1, MaxSize / 2 + 1 + i, 0, MaxSize - 1);
    385         if(Arr1[MaxSize / 2 + 1 + i] != MaxSize / 2 + 1 + i)
    386              printf("Select error: %d %d
    ", MaxSize / 2 + 1 + i, Arr1[MaxSize / 2 + 1 + i]);
    387          else
    388              printf("Select works
    ");
    389     }
    390     return 0;
    391 }
  • 相关阅读:
    Python股票分析系列——系列介绍和获取股票数据.p1
    快速相关
    特别长序列的快速卷积
    长序列的快速卷积
    快速卷积
    素因子快速傅里叶变换
    用一个N点复序列的FFT同时计算两个N点实序列离散傅里叶变换
    实序列快速傅里叶变换(二)
    实序列快速傅里叶变换(一)
    java 对于手机号码、邮箱、银行卡号脱敏一条龙服务
  • 原文地址:https://www.cnblogs.com/moon1992/p/7500077.html
Copyright © 2020-2023  润新知