直接插入排序、希尔排序、快速排序、堆排序算法比较

╰+攻爆jí腚メ 2021-12-08 22:15 330阅读 0赞

直接插入排序、希尔排序、快速排序、堆排序算法比较

进行典型内部排序算法的比较,随机产生整数样本,进行四种排序,并比较各种排序算法的执行时间。

  1. #include "stdio.h"
  2. #include "stdlib.h"
  3. #include "conio.h"
  4. #include "time.h"
  5. #define MAXSIZE 20
  6. typedef struct{
  7. int key;
  8. }RedType;
  9. typedef struct{ //定义顺序表的存储结构
  10. RedType *r; //存储空间基址,r[0]闲置或用作哨兵或用作缓冲区/
  11. int length; //顺序表的长度
  12. }SqList;
  13. void InitSqList(SqList *L){
  14. L->r=(RedType *)malloc((MAXSIZE+1)*sizeof(RedType));
  15. L->length=0;
  16. }//InitSqList
  17. void CreateSqList(SqList *L){//输入数据元素个数,随机产生整数样本
  18. int i;
  19. srand((unsigned)time(0));
  20. printf("\n请输入顺序表的长度: ");
  21. scanf("%d",&L->length);
  22. for ( i=1; i<=L->length; i++){
  23. L->r[i].key=rand()%100;//随机产生整数样本
  24. }
  25. printf("\n\n未排序的数据为:\n");
  26. for( i=1; i<=L->length; i++)
  27. printf("%8d",L->r[i]);
  28. }//CreateSqList
  29. /*************************************直接插入排序********************************************/
  30. void InsertSort(SqList *L){//直接插入排序
  31. int i,j;
  32. if(!L->length){
  33. printf("该顺序表为空!");
  34. }
  35. for(i=2; i<=L->length; i++)
  36. if(L->r[i].key < L->r[i-1].key){
  37. L->r[0].key=L->r[i].key;//复制哨兵
  38. for(j=i-1; L->r[0].key<L->r[j].key; j--){
  39. L->r[j+1].key=L->r[j].key;//元素后移
  40. }//for
  41. L->r[j+1].key = L->r[0].key;//元素插入
  42. }//if
  43. }//InsertSort
  44. /*************************************希尔排序********************************************/
  45. void shellSort(SqList *L,int dk){//希尔排序
  46. int i,j;
  47. for(i=dk+1; i<=L->length; i++)
  48. if(L->r[i].key < L->r[i-1].key){
  49. L->r[0].key=L->r[i].key;//复制哨兵
  50. for(j=i-dk; j>0&&L->r[0].key<L->r[j].key; j-=dk)
  51. L->r[j+dk].key = L->r[j].key;//元素后移
  52. L->r[j+dk].key = L->r[0].key;//元素插入
  53. }//if
  54. } //shellSort
  55. void shellInsert(SqList *L){
  56. int dk;
  57. for(dk=L->length; dk>0; dk=dk/2){
  58. shellSort(L,dk);//每次的增量都为dk/2,最终变为1
  59. } //当dk变为1是就是最基本的直接插入排序
  60. }//shellSqList
  61. /*************************************快速排序********************************************/
  62. int Partition(SqList *L, int low, int high){
  63. int pivotkey;
  64. L->r[0].key = L->r[low].key;
  65. pivotkey = L->r[low].key;
  66. while(low<high){
  67. while(low<high && L->r[high].key >= pivotkey) --high;
  68. L->r[low].key = L->r[high].key;
  69. while(low<high && L->r[low].key <= pivotkey) ++low;
  70. L->r[high].key = L->r[low].key;
  71. }//while
  72. //当low=high时跳出循环
  73. L->r[low].key = L->r[0].key;
  74. return low;
  75. }//Partition
  76. void QSort(SqList *L, int low, int high){//递归快速排序
  77. int pivotloc;
  78. if(low<high){
  79. pivotloc = Partition(L, low, high);
  80. QSort(L, low, pivotloc-1);
  81. QSort(L, pivotloc+1, high);
  82. }
  83. }//QSort
  84. /*************************************堆排序********************************************/
  85. void HeapAdjust(SqList *L, int s, int m){
  86. int j,rc;
  87. rc = L->r[s].key;
  88. for(j=2*s; j<=m; j*=2){
  89. if(j<m && L->r[j].key < L->r[j+1].key) ++j;
  90. if(rc > L->r[j].key) break;
  91. L->r[s].key = L->r[j].key;
  92. s = j;
  93. }
  94. L->r[s].key = rc;
  95. }//HeapAdjust
  96. void HeapSort(SqList *L){
  97. int i,temp;
  98. for (i=L->length/2; i>0; i--)
  99. HeapAdjust(L,i,L->length);
  100. for (i=L->length; i>1; i--){
  101. temp = L->r[1].key;
  102. L->r[1].key = L->r[i].key;
  103. L->r[i].key = temp;
  104. HeapAdjust(L,1,i-1);
  105. }
  106. }//HeapSort
  107. /*************************************输出函数********************************************/
  108. void outputSqList(SqList *L){//输出排序之后的元素
  109. int i;
  110. printf("\n该顺序表的长度为::%d\n",L->length);
  111. printf("\n\n排序了的数据为 : \n");
  112. for(i=1; i<=L->length; i++){
  113. printf("%8d",L->r[i].key);
  114. }
  115. printf("\n");
  116. }//outputSqList
  117. /*************************************复制链表函数********************************************/
  118. void CopySqList(SqList *L, SqList *L_COPY){
  119. int i;
  120. if ( !L->length ){
  121. printf("该顺序表为空!\n");
  122. }
  123. else{
  124. for (i=1; i<=L->length; i++)
  125. L_COPY->r[i].key = L->r[i].key;
  126. L_COPY->length = L->length;
  127. }
  128. }//CopySqList
  129. int main(){
  130. SqList L, L_COPY;//L为初始顺序表 ,L_COPY为L的副本,用于排序
  131. clock_t start,finish;
  132. int select,flag;//用户输入的选项
  133. flag = 1;
  134. InitSqList(&L);
  135. InitSqList(&L_COPY);
  136. CreateSqList(&L);
  137. while(flag){
  138. //mnum=0;cnum=0;
  139. CopySqList(&L,&L_COPY);
  140. printf("\n请输入选:\n1. 直接插入排序\n2. 希尔排序\n3. 快速排序\n4. 堆排序\n5.退出\n");
  141. scanf("%d",&select);
  142. switch(select){
  143. case 1:
  144. start=clock();
  145. InsertSort(&L_COPY);
  146. finish=clock();
  147. break;
  148. case 2:
  149. start=clock();
  150. shellInsert(&L_COPY);
  151. finish=clock();
  152. break;
  153. case 3:
  154. start=clock();
  155. QSort(&L_COPY,1,L.length);
  156. finish=clock();
  157. break;
  158. case 4:
  159. start=clock();
  160. HeapSort(&L_COPY);
  161. finish=clock();
  162. break;
  163. case 5:
  164. flag=0;
  165. exit(0);
  166. }
  167. outputSqList(&L_COPY);
  168. //printf("\n排序花的时间 : %lf Seconds\n",double(finish-start));
  169. }
  170. return 0;
  171. }

最后对,这些排序算法的复杂度进行一下简单的比较













































算法种类 时间复杂度 空间复杂度 是否稳定
最好情况 平均情况 最坏情况
直接插入排序 O(n) O(n²) O(n²) O(1)
希尔排序   O(1)
快速排序 O(nlog₂n) O(nlog₂n) O(n²) O(log₂n)
堆排序 O(nlog₂n) O(nlog₂n) O(nlog₂n) O(1)

发表评论

表情:
评论列表 (有 0 条评论,330人围观)

还没有评论,来说两句吧...

相关阅读