• 冒泡排序、简单选择排序、直接插入排序、希尔排序


    冒泡排序(Bubble Sort)的基本思想:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。时间复杂度为O(n2).

    简单选择排序(Simple Selection Sort)的基本思想:通过n-i次关键字之间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i个记录交换。应该说,尽管与冒泡排序同为O(n2), 但简单选择排序的性能上还是要略优于冒泡排序。

    直接插入排序(Straight Insertion Sort)的基本思想:将一个记录插入到前面已经排序好的有序表中,从而得到一个新的、记录数不断加1的有序表。直接插入排序法的时间复杂度为O(n2) 。从这里也看出,同样的O(n2)时间复杂度,直接插入排序法比冒炮和简单选择排序的性能要好一些。

    希尔排序(Shell Sort)基本思想:将相隔某个增量的记录组成一个子序列,在这些子序列内分别进行直接插入排序,得到基本有序的序列,最后在将增量为1的记录(即整个序列)的进行一次直接插入排序。其实希尔排序就是直接插入排序的改进。大量的研究表明,当增量序列为dlta[k]=2t-k+1-1 ( 0 <=k<=t <= [log2 (n+l)])时,可以获得不错的效率, 其时间复杂度为O(n3/2,要好于直接排序的o(n2)。需要注意的是, 增量序列的最后一个增量值必须等于1 才行。另外由于记录是跳跃式的移动,使得排序的效率提高,但也使得希尔排序并不是一种稳定的排序算法。

    堆排序(Heap Sort) 的基本思想是:将待排序的序列构造成一个大顶堆。此时,整个序列的最大值就是堆顶的根结点。将官移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值) .然后将剩余的n - 1 个序列重新构造成一个堆,这样就刽寻到n 个元素中的次小值。如此反复执行, 便能得到一个有序序列了。其实,堆排序就是对简单选择排序进行的一种改进,这种改进效果是非常明显的。堆排序的时间复杂度是O(nlogn)。由于堆排序对原始记录的排序状态并不敏感,因此它无论是最好、最坏和平均时间复杂度均为O(nlogn) 。这在性能上显然要远远好过于冒泡、简单选择、直接插入的O(n2)的时间复杂度了。

    快速排序(Quick Sort)的基本思想是:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行同样的排序,依次递归达到整个序列有序的目的。对于枢轴pivot的选取可以采用三数取中(median of three)法,即取三个关键字先进行排序,将中间作为枢轴,一般是取左端、右端和中间三个数,也可以随机选取。对于待排序列较长的,可采用九数取中的方法。此外,还可以优化一些不必要的交换。优化小数组的排序,即当序列较长时采用快排,较短时采用直接插入排序,设置一个阈值就可以了。快速排序算法经过多次的优化之后,在整体性能上,依旧是排序算法的王者。

    归并排序( Merging Sort) 的基本思想是:假设初始序列含有n 个记录, 则可以看成是n 个有序的子序列,每个子序列的长度为1 ,然后两两归并,得到[n/2] <[x]表示不小于x 的最小整数)个长度为2 或1 的有序子序列;再两两归并,……,如此重复, 直至得到一个长度为n 的有序序列为止,这种排序方法称为2 路归并排序.

      1 #include "stdafx.h"
      2 
      3 #include "stdio.h" 
      4 #define TRUE 1 
      5 #define FALSE 0
      6 #define MAX_LENGTH_INSERT_SORT 5
      7 
      8 void bubblesort(int *list, int index);
      9 void selectsort(int *list, int index);
     10 void insertsort(int *list, int index);
     11 void shellsort(int *list, int index);
     12 void heapsort(int *list, int index);
     13 void heapadjust(int *list, int s, int m);
     14 void quicksort(int *list, int index);
     15 void Qsort(int *list, int low, int high);
     16 int partition(int *list, int low, int high);
     17 
     18 typedef int status;
     19 int list[20];    //默认最大长度为20
     20 int temp;
     21 int i, j;
     22 int node;
     23 status change = TRUE;
     24 
     25 void swap(int *list, int i, int j)//交换元素
     26 {
     27     temp = list[i];
     28     list[i] = list[j];
     29     list[j] = temp;
     30 }
     31 
     32 void main(void)
     33 {
     34     int index = 0;
     35     printf("Please input the value you want to sort(exit for 0):
    ");
     36     scanf_s("%d", &node);
     37     while (node != 0)
     38     {
     39         list[index] = node;
     40         index += 1;
     41         scanf_s("%d", &node);
     42     }
     43     //bubblesort(list, index);
     44     //selectsort(list, index);
     45     //insertsort(list, index);
     46     //shellsort(list, index);//wrong
     47     //heapsort(list, index);
     48     quicksort(list, index);
     49 }
     50 
     51 void bubblesort(int *list, int index) //冒泡排序 时间复杂度O(n2)
     52 {
     53     for (j = 0; j<index && change; j++)
     54     {
     55         change = FALSE;
     56         for (i = 1; i<index - j; i++)
     57         {
     58             if (list[i - 1]>list[i])
     59             {
     60                 swap(list, i - 1, i);
     61                 change = TRUE;
     62             }
     63         }
     64     }
     65     printf("
    冒泡排序后为:    ");
     66     for (i = 0; i < index; i++)
     67     {
     68         printf("%d ", list[i]);
     69     }
     70 
     71 }
     72 
     73 void selectsort(int *list, int index)//简单选择排序  时间复杂度O(n2)
     74 {
     75     int min;
     76     for (i = 0; i < index - 1; i++)
     77     {
     78         min = i;
     79         for (j = i + 1; j < index; j++)
     80         {
     81             if (list[min]>list[j])
     82             {
     83                 min = j;
     84             }
     85         }
     86         if (min != i)
     87         {
     88             swap(list, min, i);
     89         }
     90     }
     91     printf("
    简单选择排序后为:");
     92     for (i = 0; i < index; i++)
     93     {
     94         printf("%d ", list[i]);
     95     }
     96 }
     97 
     98 void insertsort(int *list, int index)//直接插入排序  时间复杂度O(n2)
     99 {
    100     for (i = 1; i < index; i++)
    101     {
    102         if (list[i - 1]>list[i])
    103         {
    104             temp = list[i];
    105             for (j = i; j >= 1 && list[j - 1] > temp; j--)
    106             {
    107                 list[j] = list[j - 1];
    108             }
    109             list[j] = temp;
    110         }
    111     }
    112     printf("
    直接插入排序后为:");
    113     for (i = 0; i < index; i++)
    114     {
    115         printf("%d ", list[i]);
    116     }
    117 }
    118 void shellsort(int *list, int index)   //希尔排序  时间复杂度为O(nr),(1<r<2)
    119 {
    120     int length = index;
    121     while (length>1)
    122     {
    123         length = length / 3 + 1;       //间隔长度
    124         for (i = length; i < length; i++)
    125         {
    126             if (list[i] < list[i - length])
    127             {
    128                 temp = list[i];
    129                 for (j = i - length; j >= 0 && list[j]>temp; j -= length)
    130                 {
    131                     list[j + length] = list[j];      //这一行的j比下一行的j大length
    132                 }
    133                 list[j + length] = temp;            //这一行的j比上一行的j小length
    134             }
    135         }
    136     }
    137     printf("
    希尔排序后为:    ");
    138     for (i = 0; i < index; i++)
    139     {
    140         printf("%d ", list[i]);
    141     }
    142 }
    143 
    144 void heapsort(int *list, int index)//堆排序  时间复杂度为O(nlogn)  不稳定排序
    145 {
    146     for (i = index / 2; i>0; i--)
    147     {
    148         heapadjust(list, i, index);
    149     }
    150     for (i = index; i > 1; i--)
    151     {
    152         swap(list, 0, i - 1);
    153         heapadjust(list, 1, i - 1);
    154     }
    155     printf("
    堆排序后为:      ");
    156     for (i = 0; i < index; i++)
    157     {
    158         printf("%d ", list[i]);
    159     }
    160 }
    161 
    162 void heapadjust(int *list, int s, int m)   //生成大顶堆
    163 {
    164     temp = list[s - 1];                     //数组list是从0开始,而堆是从1开始,所以要减1;
    165     for (j = 2 * s; j <= m; j *= 2)
    166     {
    167         if (j < m && list[j - 1] < list[j])  //比较结点左孩子和右孩子的大小
    168             ++j;
    169         if (temp >= list[j - 1])     //比较孩子中的较大者和结点的大小
    170             break;
    171         list[s - 1] = list[j - 1];    //交换
    172         s = j;
    173     }
    174     list[s - 1] = temp;//插入;
    175 }
    176 
    177 void quicksort(int *list, int index)//快速排序,冒泡排序的升级版 时间复杂度O(nlogn)
    178 {
    179     Qsort(list, 0, index - 1);
    180     printf("
    快速排序后为:    ");
    181     for (i = 0; i < index; i++)
    182     {
    183         printf("%d ", list[i]);
    184     }
    185 }
    186 void Qsort(int *list, int low, int high)
    187 {
    188     int pivot;
    189     if (low < high)//if((high-low)>MAX_LENGTH_INSERT_SORT),优化,当high-low大于某个常数时用快速排序
    190     {
    191         pivot = partition(list, low, high);
    192 
    193         Qsort(list, low, pivot - 1);
    194         Qsort(list, pivot + 1, high);
    195     }
    196     //else
    197     //insertsort(list, high-low);
    198 }
    199 int partition(int *list, int low, int high)
    200 {
    201     int pivotkey;
    202 
    203     int m = low + (high - low) / 2;//三数取中法  ,对于较大的待排序列可使用九数取中
    204     if (list[low] > list[high])
    205     {
    206         swap(list, low, high);
    207     }
    208     if (list[m] > list[high])//交换中间和右端,保证中间较小
    209     {
    210         swap(list, m, high);
    211     }
    212     if (list[m] > list[low])//交换中间和左端,保证中间值放在low位置
    213     {
    214         swap(list, m, low);
    215     }
    216 
    217     pivotkey = list[low];
    218     while (low < high)
    219     {
    220         while (low < high&&list[high] >= pivotkey)
    221         {
    222             high--;
    223         }
    224         list[low] = list[high];   //采用替换而不交换,减少不必要的交换        swap(list, low, high);
    225         while (low < high&&list[low] <= pivotkey)
    226         {
    227             low++;
    228         }
    229         list[high] = list[low];  //采用替换而不交换,减少不必要的交换 swap(list, low, high);
    230 
    231     }
    232     list[low] = pivotkey;
    233     return low;
    234 
    235 }
  • 相关阅读:
    web前端的面试真题
    web前端面试真题! 面试的经历和回答只做参考1
    web前端面试真题! 面试的经历和回答只做参考
    html面试资料
    angluar.js的核心介绍
    解决 Chrome支持小于12px 的文字
    div居中效果出现的问题和解决方法
    li和li之间的bug解决方法
    前端面试题笔试考题和答案
    html5新增的标签和使用的方法
  • 原文地址:https://www.cnblogs.com/hhboboy/p/4389487.html
Copyright © 2020-2023  润新知