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

冒泡排序(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 }
原文地址:https://www.cnblogs.com/hhboboy/p/4389487.html