• 排序


    简单排序(前三种就是简单排序)
    void X_sort(ElementType A[ ], int N)
    1.大多数情况下,为简单期间,讨论从小到大的整数排序
    2.N是正整数
    3.只讨论基于比较的排序(> = <有定义)
    4.只讨论内部排序
    5.稳定性:任意两个相等的数据,排序前后的相对位置不发生改变
    6.没有一种排序是任何情况下都是变现最好的

    1.冒泡排序

     1 void Bubble_sort(ElementType A[], int N)
     2 {
     3     int flag, i, j;
     4     for (i = N - 1; i >= 0; i--)        //N- 1趟冒泡
     5     {
     6         flag = 0;
     7         for (j = 0; j < i; j++)
     8         {
     9             if (A[j] > A[j + 1])
    10             {
    11                 swap(&A[j], &A[j + 1]);
    12                 flag = 1;                //标识发生了交换
    13             }
    14         }
    15         if (flag == 0) break;        //全称无交换
    16     }
    17 }

    或者是

     1 void Bubble_sort(ElementType A[], int N)
     2 {
     3     int flag, i, j;
     4     for (i = 0; i < N - 1; i++)
     5     for (j = 0; j < N - i - 1; j++)
     6     {
     7         if (A[j] > A[j + 1])
     8             swap(&A[j], &A[j + 1]);
     9     }
    10 
    11 }

    算法复杂度:
    最好情况:顺序 T = O(N)
    最坏情况:逆序 T = O(N^2)

    2.插入排序

     1 void Insertion_Sort(ElementType A[], int N)
     2 {
     3     int i, j;
     4     ElementType tmp;
     5     for (i = 1; i < N; i++)
     6     {
     7         tmp = A[i];
     8         for (j = i; j > 0 && A[j - 1] > tmp; j--)
     9             A[j] = A[j - 1];
    10         A[j] = tmp;
    11     }
    12 }

    3.选择排序

     1 void _Sort(ElementType A[], int N)
     2 {
     3     int i, k, j;
     4     for (i = 0; i < N - 1; i++)
     5     {
     6         k = i;
     7         for (j = i; j < N; j++)
     8         {
     9             if (A[k]> A[j])
    10                 k = j;
    11         }
    12         swap(&A[k], &A[i]);
    13     }
    14 }

    4.希尔排序:如果增量元素不互质,则小增量可能根本不起作用,则增量的选取可以采用Hibbard或Sedgewick增量序列

     1 void Shell_sort(ElementType A[], int N)
     2 {
     3     int i, j, increament;
     4     ElementType temp;
     5     for (increament = N / 2; increament > 0; increament /= 2)
     6     {
     7         for (i = increament; i < N; i++)
     8         {
     9             temp = A[i];
    10             for (j = i; j >= increament; j -= increament)
    11             {
    12                 if (A[j - increament] > temp)
    13                     A[j] = A[j - increament];
    14                 else
    15                     break;
    16             }
    17 
    18             A[j] = temp;
    19         }
    20     }
    21 }

    或:

     1 void Shell_sort(ElementType A[], int N)
     2 {
     3     int i, j, increament;
     4     ElementType temp;
     5     for (increament = N / 2; increament > 0; increament /= 2)
     6     {
     7         for (i = increament; i < N; i++)
     8         {
     9             temp = A[i];
    10             for (j = i; j >= increament && A[j - increament] > temp; j -= increament)
    11                 A[j] = A[j - increament];
    12             A[j] = temp;
    13         }
    14     }
    15 }

    5.堆排序:
    //将树调整成最大堆

     1 void PercDown(ElementType A[], int i, int N)
     2 {
     3     int child;
     4     ElementType temp;
     5     for (temp = A[i]; (2 * i + 1) < N; i = child)
     6     {
     7         child = 2 * i + 1;
     8         if (child != N - 1 && A[child] < A[child + 1])
     9             child++;
    10         if (temp > A[child])
    11             break;
    12         else
    13             A[i] = A[child];
    14     }
    15     A[i] = temp;
    16 }
    17 
    18 void Heap_sort(ElementType A[], int N)
    19 {
    20     int i;
    21     for (i = N / 2; i >= 0; i--)        //BuildHeap
    22         PercDown(A, i, N);
    23     for (i = 0; i < N - 1; i++)            //DeleteMax
    24     {
    25         swap(&A[0], &A[N - 1 - i]);
    26         PercDown(A, 0, N - i - 1);
    27     }
    28 }
    29 
    30 DeleteMax还可以写成这样
    31 for (i = N - 1; i > 0; i--)            //DeleteMax
    32     {
    33         swap(&A[0], &A[i]);
    34         PercDown(A, 0, i);
    35     }


    6.1归并排序(递归实现)

     1 //Left = strart of left half, Right = start of right half, RightEnd = end of right half
     2 void Merge(ElementType A[], ElementType TmpArray[],
     3     int Left, int Right, int RightEnd)
     4 {
     5     int LeftEnd, SumNum, temp, i;
     6     temp = Left;
     7     LeftEnd = Right - 1;
     8     SumNum = RightEnd - Left + 1;
     9 
    10     //main loop
    11     while (Left <= LeftEnd && Right <= RightEnd)        
    12     {
    13         if (A[Left] < A[Right])
    14             TmpArray[temp++] = A[Left++];
    15         else
    16             TmpArray[temp++] = A[Right++];
    17     }
    18     while (Left <= LeftEnd)                //copy rest of first half
    19         TmpArray[temp++] = A[Left++];
    20     while (Right <= RightEnd)            //copy rest of second half
    21         TmpArray[temp++] = A[Right++];    
    22 
    23     for (i = 0; i < SumNum; i++, RightEnd--)        //copy TempArray back
    24         A[RightEnd] = TmpArray[RightEnd];
    25 }
    26 
    27 void MSort(ElementType A[], ElementType TmpArray[],
    28     int Left, int Right)
    29 {
    30     int Center;
    31     if (Left < Right)
    32     {
    33         Center = (Left + Right) / 2;
    34         MSort(A, TmpArray, Left, Center);
    35         MSort(A, TmpArray, Center + 1, Right);
    36         Merge(A, TmpArray, Left, Center + 1, Right);
    37     }
    38 }
    39 
    40 void Merge_sort(ElementType A[], int N)
    41 {
    42     ElementType *TmpArray;
    43     TmpArray = (ElementType*)malloc(N * sizeof(ElementType));
    44     if (TmpArray != NULL)
    45     {
    46         MSort(A, TmpArray, 0, N - 1);
    47         free(TmpArray);
    48     }
    49     else
    50         printf("No space for tmpArray[ ]!!!
    "); 
    51 }

     T = T(N/2) + T(N/2) + O(N)  ----> T= O(NlogN);

    6.2 归并排序(非递归实现)

     1 //Left = strart of left half, Right = start of right half, RightEnd = end of right half
     2 void Merge1(ElementType A[], ElementType TmpArray[],
     3     int Left, int Right, int RightEnd)
     4 {
     5     int LeftEnd, SumNum, temp;
     6     temp = Left;
     7     LeftEnd = Right - 1;
     8     SumNum = RightEnd - Left + 1;
     9 
    10     //main loop
    11     while (Left <= LeftEnd && Right <= RightEnd)        
    12     {
    13         if (A[Left] < A[Right])
    14             TmpArray[temp++] = A[Left++];
    15         else
    16             TmpArray[temp++] = A[Right++];
    17     }
    18     while (Left <= LeftEnd)                //copy rest of first half
    19         TmpArray[temp++] = A[Left++];
    20     while (Right <= RightEnd)            //copy rest of second half
    21         TmpArray[temp++] = A[Right++];    
    22 }
    23 
    24 //非递归算法 length = 当前子序列长度, Merge1将A中的元素归并到TmpA
    25 void Merge_pass(ElementType A[], ElementType TmpA[], int N, int length)
    26 {
    27     int i, j;
    28     for (i = 0; i <= N - 2 * length; i += 2 *length)
    29         Merge1(A, TmpA, i, i + length, i + 2 * length - 1);
    30     if (i + length < N)        //归并最后两个子列
    31         Merge1(A, TmpA, i, i + length, N - 1);
    32     else
    33     for (j = i; j < N; j++)        //最后只剩一个元素
    34         TmpA[j] = A[j];
    35 }
    36 
    37 void Merge_sort(ElementType A[], int N)
    38 {
    39     int length = 1;
    40     ElementType *TmpA;
    41     TmpA = (ElementType*)malloc(sizeof(ElementType) * N);
    42     if (TmpA != NULL)
    43     {
    44         while (length < N)
    45         {
    46             Merge_pass(A, TmpA, N, length);
    47             length *= 2;
    48             Merge_pass(TmpA, A, N, length);
    49             length *= 2;
    50         }
    51         free(TmpA);
    52     }
    53     else
    54         printf("Run out of memory!!!
    ");
    55 }

    7.快速排序(也是分而治之)
    最好情况:每次正好中分 T = O(NlogN)
    选主元:
    1.随机rand()函数不便宜
    2.取头、中、尾的中位数
    在程序中定义一个cutoff的阈值。当递归的数据规模充分小,则停止递归,直接调用简单排序(录入插入排序)
    //选取主元

     1 ElementType Median3(ElementType A[], int Left, int Right)
     2 {
     3     int Center = (Left + Right) / 2;
     4     if (A[Left] > A[Center])
     5         swap(&A[Left], &A[Center]);
     6     if (A[Left] > A[Right])
     7         swap(&A[Left], &A[Right]);
     8     if (A[Center] > A[Right])
     9         swap(&A[Center], &A[Right]);
    10 
    11     swap(&A[Center], &A[Right] - 1);    //将pivot藏到右边
    12     
    13     //只需要考虑A[Left + 1]……A[Right - 2]
    14     return A[Right - 1];    //返回pivot
    15 }
    16 
    17 void Quicksort(ElementType A[], int Left, int Right)
    18 {
    19     int i, j;
    20     ElementType pivot;
    21     if (Cutoff <= Right - Left)
    22     {
    23         pivot = Median3(A, Left, Right);
    24         i = Left, j = Right - 1;
    25         for (;;)
    26         {
    27             while (A[++i] < pivot) {}
    28             while (A[--j] > pivot) {}
    29             if (i < j)
    30                 swap(&A[i], &A[j]);
    31             else
    32                 break;
    33         }
    34         swap(&A[i], &A[Right - 1]);
    35         Quicksort(A, Left, i - 1);
    36         Quicksort(A, i + 1, Right);
    37     }
    38     else
    39         Insertion_sort(A + Left, Right - Left + 1);
    40 }
    41 
    42 
    43 void Quick_sort(ElementType A[], int N)
    44 {
    45     Quicksort(A, 0, N - 1);
    46 }

    8.表排序
    需要排序的每个元素很庞大(例如:结构体)
    间接排序:
    定义一个指针数组作为“表”(table)


    例如在表排序中用插入排序:

     1 void table_sort(ElementType A[], int N)
     2 {
     3     int i, j;
     4     int table[N];
     5     ElementType temp;
     6     for(i = 0; i < N; i++)
     7         table[i] = i;
     8     for (i = 1; i < N; i++)
     9     {
    10         temp = table[i];
    11         for (j = i; j > 0 && A[table[j - 1]] > temp; j--)
    12             table[j] = table[j - 1];
    13         table[j] = temp;
    14     }
    15 }

    9.物理排序
    N个数字的排列由若干个独立的环组成

    10.桶排序
    T(N, M) = O(M + N)

    11.基数排序
    次位优先

    排序算法的比较

  • 相关阅读:
    nginx启动
    java中有三种移位运算符
    easyUI属性汇总
    rose学习
    eclipse 启动到load workbench 后静止
    nvl函数
    Io 异常: Socket closed
    编译错误和运行时错误
    java 二进制编码
    MyFormat 幫助類
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/9543173.html
Copyright © 2020-2023  润新知