各种排序算法:
1 #include <stdio.h>
2 #include <string.h>
3 #include <ctype.h>
4 #include <stdlib.h>
5 #include <io.h>
6 #include <math.h>
7 #include <time.h>
8
9 #define OK 1
10 #define ERROR 0
11 #define TRUE 1
12 #define FALSE 0
13
14 #define MAX_LENGTH_INSERT_SORT 7 /* 用于快速排序时判断是否选用插入排序阙值 */
15
16 typedef int Status;
17
18 #define MAXSIZE 10000 /* 用于要排序数组个数最大值,可根据需要修改 */
19 typedef struct
20 {
21 int r[MAXSIZE+1]; /* 用于存储要排序数组,r[0]用作哨兵或临时变量 */
22 int length; /* 用于记录顺序表的长度 */
23 }SqList;
24
25 /* 交换L中数组r的下标为i和j的值 */
26 void swap(SqList *L,int i,int j)
27 {
28 int temp=L->r[i];
29 L->r[i]=L->r[j];
30 L->r[j]=temp;
31 }
32
33 void print(SqList L)
34 {
35 int i;
36 for(i=1;i<L.length;i++)
37 printf("%d,",L.r[i]);
38
39 printf("%d",L.r[i]);
40 printf("\n");
41 }
42
43 /* 对顺序表L作交换排序(冒泡排序初级版) */
44 void BubbleSort0(SqList *L)
45 {
46 for( int i=1; i<L->length; i++)
47 {
48 for( int j=i+1; j<=L->length; j++)
49 {
50 if(L->r[i]>L->r[j])
51 {
52 swap(L,i,j); /* 交换L->r[i]与L->r[j]的值 */
53 }
54 }
55 }
56 }
57
58 /* 对顺序表L作冒泡排序 */
59 void BubbleSort(SqList *L)
60 {
61 for(int i=1;i<L->length;i++)
62 {
63 for(int j=L->length-1;j>=i;j--) /* 注意j是从后往前循环 */
64 {
65 if(L->r[j]>L->r[j+1]) /* 若前者大于后者(注意这里与上一算法的差异)*/
66 {
67 swap(L,j,j+1); /* 交换L->r[j]与L->r[j+1]的值 */
68 }
69 }
70 }
71 }
72
73 /* 对顺序表L作改进冒泡算法 */
74 void BubbleSort2(SqList *L)
75 {
76 Status flag = TRUE; /* flag用来作为标记 */
77 for( int i=1; i<L->length && flag; i++) /* 若flag为true说明有过数据交换,否则停止循环 */
78 {
79 flag = FALSE; /* 初始为False */
80 for(int j=L->length-1; j>=i; j--)
81 {
82 if(L->r[j] > L->r[j+1])
83 {
84 swap(L, j, j+1); /* 交换L->r[j]与L->r[j+1]的值 */
85 flag = TRUE; /* 如果有数据交换,则flag为true */
86 }
87 }
88 }
89 }
90
91 // 双向冒泡法
92 void Bubble_2 ( int r[], int n)
93 {
94 int low = 0;
95 int high = n-1; //设置变量的初始值
96 int tmp,j;
97
98 while (low < high)
99 {
100 for (j = low; j< high; ++j) // 正向冒泡,找到最大者
101 if (r[j] > r[j+1])
102 {
103 tmp = r[j]; r[j] = r[j+1]; r[j+1] = tmp;
104 }
105 --high; // 修改high值, 前移一位
106 for ( j = high; j > low; --j) // 反向冒泡,找到最小者
107 if (r[j] < r[j-1])
108 {
109 tmp = r[j]; r[j] = r[j-1]; r[j-1] = tmp;
110 }
111 ++low; // 修改low值,后移一位
112 }
113 }
114
115 /*
116 多关键码排序方法:
117
118 多关键码排序按照从最主位关键码到最次位关键码或从最次位到最主位关键码的顺序逐次排序,分两种方法:
119
120 最高位优先(Most Significant Digit first)法,简称MSD法:
121 1)先按k1 排序分组,将序列分成若干子序列,同一组序列的记录中,关键码k1 相等。
122 2)再对各组按k2 排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd 对各子组排序后。
123 3)再将各组连接起来,便得到一个有序序列。扑克牌按花色、面值排序中介绍的方法一即是MSD 法。
124
125 最低位优先(Least Significant Digit first)法,简称LSD法:
126 1) 先从kd 开始排序,再对kd-1进行排序,依次重复,直到按k1排序分组分成最小的子序列后。
127 2) 最后将各个子序列连接起来,便可得到一个有序的序列, 扑克牌按花色、面值排序中介绍的方法二即是LSD 法。
128
129 原理:
130 按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。
131 有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。
132 最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。
133 基数排序基于分别排序,分别收集,所以是稳定的。
134 @param:
135 r: 原始数组
136
137 // 原理版本
138 void RadixSort(int r[], int length, int maxradix )
139 {
140 int k, lsp;
141 k = 1;
142 int n = 0; // 基数内 序号
143 int m = 1; // 个位、十位
144
145 int temp[10][length-1];
146 Empty( temp ); // 清空临时空间
147
148 while( k < maxradix ) // 遍历所有关键字
149 {
150 for(int i=0; i<length; i++) //分配过程
151 {
152 if(r[i] < m)
153 temp[0][n] = r[i];
154 else
155 lsp = (r[i]/m) % 10; //确定关键字
156
157 temp[lsp][n] = r[i];
158 n++;
159 }
160
161 CollectElement(r, temp); // 收集
162 n = 0;
163 m = m*10;
164 k++;
165 }
166 }
167 */
168 // 得到最大位数
169 int maxbit(int data[], int n)
170 {
171 int nBit = 1;
172 for(int i=0; i<n; i++)
173 {
174 int tempC = 1;
175 int p = data[i];
176 while( p/10 )
177 {
178 p = p/10;
179 tempC++;
180 }
181 if( tempC > nBit )
182 nBit = tempC;
183 }
184 return nBit;
185 }
186
187 void RadixSort(int data[], int n)
188 {
189 int* tmp = new int[n];
190 int count[10]; // 每一桶中的个数
191 int nBit = maxbit(data,n);
192 int r=1;
193
194 for(int i=0; i<nBit; i++)
195 {
196 // 装桶之前要先清桶
197 for(int i=0;i<10;i++)
198 count[i]=0;
199
200 for(i=0;i<n;i++) // 记录每个桶的个数
201 {
202 int k=data[i]/r;
203 int q=k%10;
204 count[q]++;
205 }
206 for(i=1; i<10; i++) // 计算位置
207 {
208 count[i] += count[i-1];
209 }
210 for(int j=n-1; j>=0; j--)
211 {
212 int p = data[j]/r;
213 int s = p%10;
214 tmp[count[s]-1] = data[j];
215 count[s]--;
216 }
217 for(i=0; i<n; i++)
218 {
219 data[i] = tmp[i];
220 }
221 r = r*10; // 更高一位
222
223 }
224
225 }
226
227
228 // 计数排序
229 void CountSort(int* pData, int n)
230 {
231 int* pCout = NULL; // 记数的指针
232 int* pSort = NULL; // 暂存排序结果的指针
233 pCout = (int*)malloc(sizeof(int) * n); // 申请空间
234 pSort = (int*)malloc(sizeof(int) * n);
235
236
237 // 初始化记数为0
238 for (int i = 0; i < n; ++i)
239 {
240 pCout[i] = 0;
241 }
242 // 统计相同元素的个数
243 for (int i = 0; i < n; ++i)
244 {
245 ++pCout[pData[i]];
246 }
247 // pCout[i]中是 <= i 的元素个数
248 for (int i = 1; i < n; ++i)
249 {
250 pCout[i] += pCout[i-1];
251 }
252 for (int i = 0; i < n; ++i)
253 {
254 pSort[pCout[pData[i]]] = pData[i]; // 把每一个元素放在数组中相应的位置;因为pCout[pData[i]]的值就是不比他大数据的个数;
255 pCout[pData[i]]--; // 如果有相同数据的元素先减1
256 }
257 // 排序结束,复制到原来数组中
258 for (int i = 0; i < n; ++i)
259 {
260 pData[i] = pSort[i];
261 }
262 // 释放申请的空间
263 free(pCout);
264 free(pSort);
265 }
266
267 /* 对顺序表L作简单选择排序 */
268 void SelectSort(SqList *L)
269 {
270 int min;
271 for( int i=1; i<L->length; i++)
272 {
273 min = i; /* 将当前下标定义为最小值下标 */
274 for ( int j = i+1;j<=L->length;j++)/* 循环之后的数据 */
275 {
276 if (L->r[min] > L->r[j]) /* 如果有小于当前最小值的关键字 */
277 min = j; /* 将此关键字的下标赋值给min */
278 }
279 if(i != min) /* 若min不等于i,说明找到最小值,交换 */
280 swap(L, i, min); /* 交换L->r[i]与L->r[min]的值 */
281 }
282 }
283
284 // 简单选择排序的改进 二元选择排序
285 void SelectSort(int r[],int n)
286 {
287 int i, j, min, max, tmp;
288 for (i = 1; i <= n/2; i++)
289 {
290 // 做不超过n/2趟选择排序
291 min = i; max = i ; // 分别记录最大和最小关键字记录位置
292 for (j = i+1; j <= n-i; j++)
293 {
294 if (r[j] > r[max])
295 {
296 max = j;
297 continue;
298 }
299 if (r[j] < r[min])
300 {
301 min = j;
302 }
303 }
304
305 tmp = r[i-1]; r[i-1] = r[min]; r[min] = tmp; // swap(a, min, i-1);
306 tmp = r[n-i]; r[n-i] = r[max]; r[max] = tmp; // swap(a, max, n-i)
307 }
308 }
309
310 /* 对顺序表L作直接插入排序
311
312 插入排序(insert sorting)思想:
313 当插入第i个元素时,前面的v[0],v[1],v[2]......v[i-1],已经排好序了.
314 这时用v[i]的插入码与 v[i-1],v[i-2],......排序码进行比较,
315 找到插入的位置即插入v[i],原来位置上的元素从后向前依次后移。
316
317 时间复杂度: 平均比较次数O(n2),平均移动次数 O(n2).
318 直接插入排序是一种稳定的排序。元素大部分有序时 效率会更高,这时比较次数和移动次数都会减少。
319
320 */
321 void InsertSort(SqList *L)
322 {
323 int j;
324 for( int i=2; i<=L->length; i++)
325 {
326 if (L->r[i] < L->r[i-1]) /* 需将L->r[i]插入有序子表 */
327 {
328 L->r[0] = L->r[i]; /* 设置哨兵 */
329 for( j=i-1; L->r[j] > L->r[0]; j--)
330 L->r[j+1] = L->r[j]; /* 记录后移 */
331
332 L->r[j+1] = L->r[0]; /* 插入到正确位置 */
333 }
334 }
335 }
336
337 /* 对顺序表L作希尔排序
338
339 希尔排序(Shell sort)基本思想: 改进的直接插入算法。
340 设待排序的元素序列有n个元素,首先取一整数gap(<n)作为间隔,将全部元素分为gap个子序列,
341 所有距离为gap的元素 放在同一序列中,在每个子序列中分别进行直接插入排序。
342 然后缩小gap,例如gap = gap/2,重复上述的子序列划分与排序工作。
343 开始由于gap取值大,每个子序列元素少,排序速度快,待排序后期,
344 gap值逐渐变小,子序列元素变多,但由于前面的工作基础,大多数元素已经有序,所以排序速度快。
345
346
347 希尔排序是一种不稳定的排序
348 */
349 void ShellSort(SqList *L)
350 {
351 int j, k = 0;
352 int d = L->length;
353 do
354 {
355 d = d/3 + 1; /* 增量序列 */
356 for(int i=d+1; i<=L->length; i++)
357 {
358 if (L->r[i] < L->r[i-d]) /* 需将L->r[i]插入有序增量子表 */
359 {
360 L->r[0] = L->r[i]; /* 暂存在L->r[0] */
361 for( j = i-d; j>0 && L->r[0]<L->r[j]; j -= d)
362 L->r[j+d]=L->r[j]; /* 记录后移,查找插入位置 */
363
364 L->r[j+d]=L->r[0]; /* 插入 */
365 }
366 }
367 printf("第%d趟排序结果: ",++k);
368 print(*L);
369 }
370 while( d > 1 );
371
372 }
373
374
375 /*
376 大根堆排序的基本思想:
377 1) 先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区;
378 2) 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,
379 由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key;
380 3) 由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。
381 然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,
382 由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系 R[1..n-2].keys≤R[n-1..n].keys,同样要将R[1..n-2]调整为堆。
383 */
384
385 /*
386 @brief:
387 已知L->r[s..len]中记录的关键字除L->r[s]之外均满足堆的定义,
388 本函数调整L->r[s]的关键字,使L->r[s..len]成为一个大顶堆
389 @param:
390 cur: 当前位置 s
391 len: 当前状态的最大值
392
393 m:当前堆的大小
394 */
395 void HeapAdjust(SqList *L, int cur, int len)
396 {
397 int temp = L->r[cur];
398 for(int j = 2*cur; j <= len; j *= 2)// 沿关键字较大的孩子结点向下筛选(大根堆)
399 {
400 if(j < len && L->r[j] < L->r[j+1])
401 ++j; // j为关键字中较大的记录的下标
402 if(temp >= L->r[j])
403 break; /* 应插入在位置 cur 上 */
404
405 L->r[cur] = L->r[j];
406 cur = j;
407 }
408 L->r[cur] = temp; /* 插入 */
409 }
410
411 /* 对顺序表L进行堆排序 */
412 void HeapSort( SqList* L )
413 {
414 for( int i = L->length/2; i>0; i--) /* 把L中的r构建成一个大根堆 */
415 HeapAdjust(L, i, L->length);
416
417 for( int i = L->length; i>1; i--)
418 {
419 swap(L, 1, i); /* 将堆顶记录和当前未经排序子序列的最后一个记录交换 */
420 HeapAdjust(L, 1, i-1); /* 将L->r[1..i-1]重新调整为大根堆 */
421 }
422 }
423
424
425 #if 0
426
427
428 #include <iostream>
429 #include <algorithm>
430
431 using std::cout;
432 using std::cin;
433 using std::endl;
434
435 template<class T>
436 class Out
437 {
438 public:
439 void operator()(T o)
440 {
441 cout<<o<<'\t';
442 }
443 };
444 template<class T>
445 void Swap(T& a,T&b)
446 {
447 if(a == b)
448 return;
449 T t=a;
450 a=b;
451 b=t;
452 }
453 inline int Rt(int idx)
454 {
455 return (idx<<1)+2;
456 }
457 inline int Lt(int idx)
458 {
459 return (idx<<1)+1;
460 }
461
462 template<class T>
463 void HeapBuild(T* A,int idx,int size)
464 {
465 int child;
466 for(; idx<=size/2; idx=child)
467 {
468 child=Lt(idx);
469 if (child<size&&A[child]>A[idx])
470 {
471 Swap(A[idx],A[child]);
472 }
473 child=Rt(idx);
474 if (child<size&&A[child]>A[idx])
475 {
476 Swap(A[idx],A[child]);
477 }
478 }
479 }
480 template<class T>
481 void HeapSort(T* A, int size)
482 {
483 if(size == 1)
484 return;
485
486 for (int i=size/2; i>=0; i--)
487 {
488 HeapBuild(A,i,size);
489 }
490 int i=size-1;
491 cout<<"swap max number:"<<A[0]<<","<<A[i]<<endl;
492 Swap(A[0],A[i]);
493 //现在得到了一个最大值,对前size-1个递归调用HeapSort
494 HeapSort(A, i);
495 }
496
497 int main()
498 {
499 int size=0;
500 cout<<"enter elements count num:"<<endl;
501 cin>>size;
502 // size = 10;
503 int* elems = new int[size];
504 // int elems[] = {1, 8, 4, 5, 6, 7, 11, 2, 3, 45};
505 cout<<"Input all elements to be sorted:"<<endl;
506 for(int i=0; i<size; cin>>elems[i++]);
507
508 HeapSort(elems,size);
509 std::for_each(elems,elems+size,Out<int>());
510 delete []elems;
511
512 system("pause");
513 return 0;
514
515 }
516
517 #endif
518
519 #pragma region MergeSort
520 /*
521 归并算法思想:
522 分而治之(divide - conquer);每个递归过程涉及三个步骤
523 1) 分解: 把待排序的 n 个元素的序列分解成两个子序列, 每个子序列包括 n/2 个元素.
524 2) 治理: 对每个子序列分别调用归并排序MergeSort, 进行递归操作
525 3) 合并: 合并两个排好序的子序列,生成排序结果.
526 */
527
528 /* 将有序的SR[i..m]和SR[m+1..n]归并为有序的TR[i..n] */
529 void Merge(int SR[],int TR[], int start, int mid, int end)
530 {
531 int j,k,l;
532 for(j=mid+1,k=start; start<=mid && j<=end; k++) /* 将SR中记录由小到大地并入TR */
533 {
534 if (SR[start] < SR[j])
535 TR[k] = SR[start++];
536 else
537 TR[k] = SR[j++];
538 }
539 if(start<=mid)
540 {
541 for(l=0; l<=mid-start; l++)
542 TR[k+l] = SR[start+l]; /* 将剩余的SR[i..m]复制到TR */
543 }
544 if(j<=end)
545 {
546 for(l=0; l<=end-j; l++)
547 TR[k+l] = SR[j+l]; /* 将剩余的SR[j..n]复制到TR */
548 }
549 }
550
551 /* 递归法 */
552 /* 将SR[s..t]归并排序为TR1[s..t] */
553 void MSort(int SR[],int TR1[], int start, int end)
554 {
555 int mid;
556 int TR2[MAXSIZE+1];
557
558 if(start == end)
559 {
560 TR1[start] = SR[start];
561 }
562 else
563 {
564 mid = (start + end)/2; /* 将SR[s..t]平分为SR[s..m]和SR[m+1..t] */
565 MSort(SR,TR2, start, mid); /* 递归地将SR[s..m]归并为有序的TR2[s..m] */
566 MSort(SR,TR2, mid+1, end); /* 递归地将SR[m+1..t]归并为有序的TR2[m+1..t] */
567
568 Merge(TR2,TR1, start, mid, end); /* 将TR2[s..m]和TR2[m+1..t]归并到TR1[s..t] */
569 }
570 }
571
572 /* 对顺序表L作归并排序 */
573 void MergeSort(SqList *L)
574 {
575 MSort(L->r, L->r, 1, L->length);
576 }
577
578
579 /* 非递归法 */
580 /*
581 @brief:
582 将SR[]中相邻长度为s的子序列两两归并到TR[]
583 @param:
584 size: 归并相邻字段的大小
585 len: 原始数据的总长度
586 */
587 void MergePass(int SR[],int TR[], int size,int len)
588 {
589 int i = 1;
590
591 while(i <= len-2*size+1)
592 {
593 Merge(SR,TR, i, i+size-1, i+2*size-1); // 两两归并(归并长度为 size 的两个相邻子序列)
594 i += 2*size;
595 }
596
597 if(i < len-size+1) // 归并最后两个序列(尚有两个子序列,其中后一个长度小于len)
598 {
599 Merge(SR,TR, i, i+size-1, len);
600 }
601 else // 若最后只剩下单个子序列
602 {
603 for( int j = i; j <= len; j++)
604 TR[j] = SR[j];
605 }
606 }
607
608 /* 对顺序表L作归并非递归排序 */
609 void MergeSort2(SqList *L)
610 {
611 int* TR = (int*)malloc( L->length * sizeof(int) ); /* 申请额外空间 */
612
613 int _size = 1;
614 while( _size < L->length )
615 {
616 MergePass(L->r, TR, _size, L->length);
617 _size *= 2; /* 子序列长度加倍 */
618
619 MergePass(TR, L->r, _size, L->length);
620 _size *= 2; /* 子序列长度加倍 */
621 }
622 }
623
624 /*
625 (归并)算法分析
626
627 1、稳定性
628 归并排序是一种稳定的排序。
629
630 2、存储结构要求
631 可用顺序存储结构,也易于在链表上实现。
632
633 3、时间复杂度
634 对长度为n的文件,需进行log(n)趟二路归并,每趟归并的时间为O(n),故其时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlgn)。
635
636 4、空间复杂度
637 需要一个辅助向量来暂存两有序子文件归并的结果,故其辅助空间复杂度为O(n),显然它不是就地排序。
638 */
639
640 #pragma endregion MergeSort
641
642 #pragma region QuickSort
643 /* 交换顺序表L中子表的记录,使枢轴记录到位,并返回其所在位置 */
644 /* 此时在它之前(后)的记录均不大(小)于它。 */
645 int Partition(SqList *L,int low,int high)
646 {
647 int pivotkey;
648
649 pivotkey = L->r[low]; /* 用子表的第一个记录作枢轴记录 */
650 while(low < high) /* 从表的两端交替地向中间扫描 */
651 {
652 while(low<high && L->r[high]>=pivotkey)
653 high--;
654 swap(L,low,high);/* 将比枢轴记录小的记录交换到低端 */
655 while(low<high && L->r[low]<=pivotkey)
656 low++;
657 swap(L,low,high);/* 将比枢轴记录大的记录交换到高端 */
658 }
659 return low; /* 返回枢轴所在位置 */
660 }
661
662 /* 对顺序表L中的子序列L->r[low..high]作快速排序 */
663 void QSort(SqList *L,int low,int high)
664 {
665 int pivot;
666 if(low < high)
667 {
668 pivot = Partition(L,low,high); /* 将L->r[low..high]一分为二,算出枢轴值pivot */
669 QSort(L, low, pivot-1); /* 对低子表递归排序 */
670 QSort(L, pivot+1, high); /* 对高子表递归排序 */
671 }
672 }
673
674 /* 对顺序表L作快速排序 */
675 void QuickSort(SqList *L)
676 {
677 QSort(L, 1, L->length);
678 }
679
680
681 /* 改进后快速排序******************************** */
682
683 /* 快速排序优化算法 */
684 int Partition1(SqList *L,int low,int high)
685 {
686 int pivotkey;
687
688 int m = low + (high - low) / 2; /* 计算数组中间的元素的下标 */
689 if (L->r[low]>L->r[high])
690 swap(L,low,high); /* 交换左端与右端数据,保证左端较小 */
691 if (L->r[m]>L->r[high])
692 swap(L,high,m); /* 交换中间与右端数据,保证中间较小 */
693 if (L->r[m]>L->r[low])
694 swap(L,m,low); /* 交换中间与左端数据,保证左端较小 */
695
696 pivotkey = L->r[low]; /* 用子表的第一个记录作枢轴记录 */
697 L->r[0] = pivotkey; /* 将枢轴关键字备份到L->r[0] */
698 while(low<high) /* 从表的两端交替地向中间扫描 */
699 {
700 while(low<high&&L->r[high]>=pivotkey)
701 high--;
702 L->r[low]=L->r[high];
703 while(low<high&&L->r[low]<=pivotkey)
704 low++;
705 L->r[high]=L->r[low];
706 }
707 L->r[low]=L->r[0];
708 return low; /* 返回枢轴所在位置 */
709 }
710
711 void QSort1(SqList *L,int low,int high)
712 {
713 int pivot;
714 if( (high-low) > MAX_LENGTH_INSERT_SORT )
715 {
716 while(low < high)
717 {
718 pivot = Partition1(L, low, high); /* 将L->r[low..high]一分为二,算出枢轴值pivot */
719 QSort1(L,low,pivot-1); /* 对低子表递归排序 */
720 QSort1(L,pivot+1,high); /* 对高子表递归排序 */
721 low=pivot+1; /* 尾递归 */
722 }
723 }
724 else
725 InsertSort(L);
726 }
727
728 /* 对顺序表L作快速排序 */
729 void QuickSort1(SqList *L)
730 {
731 QSort1(L, 1, L->length);
732 }
733
734 #pragma endregion QuickSort
735
736
737
738 #define N 9
739 int main()
740 {
741 int i;
742
743 /* int d[N]={9,1,5,8,3,7,4,6,2}; */
744 int d[N]={50,10,90,30,70,40,80,60,20};
745 /* int d[N]={9,8,7,6,5,4,3,2,1}; */
746
747 SqList l0,l1,l2,l3,l4,l5,l6,l7,l8,l9,l10;
748
749 for(i=0;i<N;i++)
750 l0.r[i+1] = d[i];
751 l0.length = N;
752
753 l1=l2=l3=l4=l5=l6=l7=l8=l9=l10=l0;
754
755 printf("排序前:\n");
756 print(l0);
757
758 printf("初级冒泡排序:\n");
759 BubbleSort0(&l0);
760 print(l0);
761
762 printf("冒泡排序:\n");
763 BubbleSort(&l1);
764 print(l1);
765
766 printf("改进冒泡排序:\n");
767 BubbleSort2(&l2);
768 print(l2);
769
770 printf("选择排序:\n");
771 SelectSort(&l3);
772 print(l3);
773
774 printf("直接插入排序:\n");
775 InsertSort(&l4);
776 print(l4);
777
778 printf("希尔排序:\n");
779 ShellSort(&l5);
780 print(l5);
781
782 printf("堆排序:\n");
783 HeapSort(&l6);
784 print(l6);
785
786 printf("归并排序(递归):\n");
787 MergeSort(&l7);
788 print(l7);
789
790 printf("归并排序(非递归):\n");
791 MergeSort2(&l8);
792 print(l8);
793
794 printf("快速排序:\n");
795 QuickSort(&l9);
796 print(l9);
797
798 printf("改进快速排序:\n");
799 QuickSort1(&l10);
800 print(l10);
801
802
803 /*大数据排序*/
804 /*
805 srand(time(0));
806 int Max=10000;
807 int d[10000];
808 int i;
809 SqList l0;
810 for(i=0;i<Max;i++)
811 d[i]=rand()%Max+1;
812 for(i=0;i<Max;i++)
813 l0.r[i+1]=d[i];
814 l0.length=Max;
815 MergeSort(l0);
816 print(l0);
817 */
818
819 system("pause");
820 return 0;
821 }