六种排序算法(插入排序、希尔排序、冒泡排序、快速排序、选择排序、堆排序)

爱被打了一巴掌 2022-04-05 03:14 340阅读 0赞
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <conio.h>
  4. #define MAX_NUM 32768
  5. typedef int ElemType;//元素类型
  6. typedef struct
  7. {
  8. ElemType key;
  9. } KeyType;//关键字的类型
  10. typedef struct
  11. {
  12. KeyType R[MAX_NUM+1];
  13. int length;
  14. }*orderList,Node;
  15. int compareTimes;//比较次数
  16. int moveTimes;//移动次数
  17. orderList init_orderList()
  18. {
  19. orderList l=(orderList)malloc(sizeof(Node));
  20. l->length=0;
  21. // printf("顺序表初始化成功");
  22. return l;
  23. }
  24. //随机产生一些数字
  25. int produce_randomNum(orderList l)
  26. {
  27. srand(time(0));
  28. int n,m,a,i;
  29. printf("随机产生1-m范围的 n个数:\n");
  30. scanf("%d %d",&m,&n);//产生n个1-m之间的数字
  31. for(i=1; i<=n; i++)
  32. {
  33. a=rand()%m+1;
  34. //printf("%d ",a);
  35. l->R[++l->length].key=a;
  36. }
  37. return n;
  38. }
  39. //打印所有数字
  40. void print_orderList(orderList l)
  41. {
  42. int i;
  43. for(i=1; i<=l->length; i++)
  44. printf("%d ",l->R[i].key);
  45. printf("\n");
  46. }
  47. //逆序
  48. void reverse(orderList l)
  49. {
  50. int i;
  51. orderList l1=init_orderList();
  52. for(i=1; i<=l->length; i++)
  53. l1->R[i].key=l->R[i].key;
  54. for(i=1; i<=l->length; i++)
  55. {
  56. l->R[i].key=l1->R[l->length-i+1].key;
  57. // printf("%d ",l1->R[i].key);
  58. }
  59. //printf("逆序输出:\n");
  60. //print_orderList(l);
  61. }
  62. //插入排序ElemType
  63. void insertSort(orderList l)
  64. {
  65. int i,j;
  66. int signal;
  67. compareTimes=moveTimes=0;
  68. for(i=2; i<=l->length; i++) //从第二个数开始依次与前面的数字比较
  69. {
  70. signal=l->R[i].key;//当前结点作为标志结点
  71. j=i-1;
  72. while(j>=1)//从当前结点下一个开始与标志结点比较
  73. {
  74. compareTimes++;
  75. if(l->R[j].key>signal)//大于标志结点,结点后移
  76. {
  77. moveTimes++;
  78. l->R[j+1]=l->R[j];
  79. j--;
  80. }
  81. if(l->R[j].key<=signal)//小于标志结点,结束
  82. break;
  83. }
  84. moveTimes++;
  85. l->R[j+1].key=signal;//第j+1个结点标志结点
  86. }
  87. printf("插入排序结果:\n");
  88. print_orderList(l);
  89. printf("比较次数%d ,移动次数:%d\n",compareTimes,moveTimes);
  90. }
  91. //希尔排序
  92. void shellSort(orderList l)
  93. {
  94. compareTimes=moveTimes=0;
  95. int gap,i,j;
  96. ElemType temp;
  97. for(gap=l->length/2; gap>0; gap/=2)
  98. {
  99. for(i=gap; i<=l->length; i++) //从每组最后开始进行插入排序
  100. {
  101. j=i;
  102. temp=l->R[j].key;//标志为当前组的最后一个
  103. while(j-gap>=1&&l->R[j-gap].key>temp)//j-gap为本组前一个数,本组还有数字并且本组当前数字大于标志数
  104. {
  105. compareTimes++;
  106. l->R[j]=l->R[j-gap];
  107. moveTimes++;
  108. j=j-gap;
  109. }
  110. compareTimes++;
  111. //本组当前数字小于标志数字
  112. l->R[j].key=temp;
  113. moveTimes++;
  114. }
  115. }
  116. printf("希尔排序结果:\n");
  117. print_orderList(l);
  118. printf("比较次数%d ,移动次数:%d\n",compareTimes,moveTimes);
  119. }
  120. //冒泡排序
  121. void buddleSort(orderList l)
  122. {
  123. compareTimes=moveTimes=0;
  124. int i,j,flag;
  125. KeyType temp;
  126. for(i=1; i<=l->length-1; i++)
  127. {
  128. flag=0;
  129. for(j=1; j<=l->length-i; j++)
  130. {
  131. compareTimes++;
  132. if(l->R[j+1].key<l->R[j].key)从最后一个数开始,比较相邻两个数的位置,如果第二个数小,就交换位置,这样一次循环后最小的就会被交换到最前面
  133. {
  134. moveTimes++;
  135. temp=l->R[j];
  136. l->R[j]=l->R[j+1];
  137. l->R[j+1]=temp;
  138. flag=1;
  139. }
  140. }
  141. if(flag==0)
  142. break;//没有发生交换,则提前终止
  143. }
  144. printf("冒泡排序结果:\n");
  145. print_orderList(l);
  146. printf("比较次数%d ,移动次数:%d\n",compareTimes,moveTimes);
  147. }
  148. //快速排序
  149. void quickSort(orderList l,int left,int right)
  150. {
  151. if(left>=right)//当左区间>=区间时,一部分的排序完成
  152. {
  153. return;
  154. }
  155. int i=left,j=right;
  156. int pivotKey=l->R[left].key;//把第一个数作为一个枢纽
  157. while(i<j)
  158. {
  159. while(i<j&&l->R[j].key>=pivotKey)//从最后一个数开始依次与枢纽比较
  160. {
  161. compareTimes++;
  162. j--;
  163. }
  164. compareTimes++;
  165. l->R[i].key=l->R[j].key;//把比枢纽小的元素交换到低端
  166. moveTimes++;
  167. while(i<j&&l->R[i].key<=pivotKey)
  168. {
  169. compareTimes++;
  170. i++;
  171. }
  172. compareTimes++;
  173. l->R[j].key=l->R[i].key;//把比枢纽大的交换到高端
  174. moveTimes++;
  175. }
  176. l->R[i].key=pivotKey;// 当前元素变成枢纽元素
  177. moveTimes++;
  178. quickSort(l,left,i-1);//枢纽左面的数形成左区间,里面的数都比枢纽小
  179. quickSort(l,i+1,right);//枢纽右面的数字形成右区间,里面的书都比枢纽大
  180. //对左右两部分分别进行快速排序
  181. }
  182. void selectSort(orderList l)
  183. {
  184. int i,j,min,temp;
  185. compareTimes=moveTimes=0;
  186. for(i=1; i<=l->length-1; i++)
  187. {
  188. min=i;
  189. for(j=i+1; j<=l->length; j++)
  190. {
  191. if(l->R[j].key<l->R[min].key)
  192. {
  193. min=j;
  194. compareTimes++;
  195. moveTimes++;
  196. }
  197. compareTimes++;
  198. }
  199. if(min!=i)
  200. {
  201. temp=l->R[i].key;
  202. l->R[i].key=l->R[min].key;
  203. l->R[min].key=temp;
  204. moveTimes++;
  205. }
  206. compareTimes++;
  207. }
  208. printf("简单选择排序结果:\n");
  209. print_orderList(l);
  210. printf("比较次数%d ,移动次数:%d\n",compareTimes,moveTimes);
  211. }
  212. void heapAdjust(orderList l,int par,int length)
  213. {
  214. int temp=l->R[par].key; //保存当前父节点
  215. int child=2*par;
  216. while(child<=length)
  217. {
  218. if(child+1<length&&l->R[child+1].key>l->R[child].key)//有右结点并且右结点小于左结点
  219. child++;
  220. compareTimes++;
  221. if(temp>=l->R[child].key)//父节点如果已经大于孩子结点,提前结束
  222. break;
  223. compareTimes++;
  224. l->R[par].key=l->R[child].key;//否则,把孩子结点的值赋给父结点
  225. moveTimes++;
  226. //选取孩子结点左结点,继续向下筛选
  227. par=child;
  228. child=2*par;
  229. }
  230. l->R[par].key=temp;
  231. //恢复原来的父结点
  232. }
  233. void heapSort(orderList l)
  234. {
  235. int i,j,temp;
  236. compareTimes=moveTimes=0;
  237. for(i=l->length/2; i>=1; i--)
  238. heapAdjust(l,i,l->length);
  239. for(i=l->length; i>=1; i--)
  240. {
  241. temp=l->R[i].key;
  242. l->R[i].key=l->R[1].key;
  243. l->R[1].key=temp;
  244. moveTimes++;
  245. heapAdjust(l,1,i);
  246. }
  247. printf("堆排序结果:\n");
  248. print_orderList(l);
  249. printf("比较次数%d ,移动次数:%d\n",compareTimes,moveTimes);
  250. }
  251. int main()
  252. {
  253. /* orderList l=init_orderList();
  254. int n=produce_randomNum(l);*/
  255. int choice;
  256. orderList l;
  257. int n;
  258. while(1)
  259. {
  260. printf("\t\t\t\t**************排序****************\n");
  261. printf("\t\t\t\t* *\n");
  262. printf("\t\t\t\t* 1.初始化数据 *\n");
  263. printf("\t\t\t\t* 2.直接插入排序 *\n");
  264. printf("\t\t\t\t* 3.希尔排序 *\n");
  265. printf("\t\t\t\t* 4.冒泡排序 *\n");
  266. printf("\t\t\t\t* 5.快速排序 *\n");
  267. printf("\t\t\t\t* 6.简单选择排序 *\n");
  268. printf("\t\t\t\t* 7.堆排序 *\n");
  269. printf("\t\t\t\t* 8.打印数据 *\n");
  270. printf("\t\t\t\t* 9.逆序输出 *\n");
  271. printf("\t\t\t\t* *\n");
  272. printf("\t\t\t\t* 0.退出 *\n");
  273. printf("\t\t\t\t**********************************\n");
  274. printf("请选择(0-6):\n");
  275. scanf("%d",&choice);
  276. switch(choice)
  277. {
  278. case 1:
  279. l=init_orderList();
  280. n=produce_randomNum(l);
  281. break;
  282. case 2:
  283. insertSort(l);//直接插入排序
  284. getch();
  285. printf("正序:\n");
  286. reverse(l);
  287. insertSort(l);
  288. getch();
  289. printf("逆序:\n");
  290. reverse(l);
  291. insertSort(l);
  292. break;
  293. case 3:
  294. shellSort(l);//希尔排序
  295. getch();
  296. printf("正序:\n");
  297. shellSort(l);//希尔排序
  298. getch();
  299. printf("逆序:\n");
  300. reverse(l);
  301. shellSort(l);//希尔排序
  302. break;
  303. case 4:
  304. buddleSort(l);//冒泡排序
  305. break;
  306. case 5://快速排序
  307. compareTimes=moveTimes=0;
  308. quickSort(l,1,n);
  309. printf("快速排序结果:\n");
  310. print_orderList(l);
  311. printf("比较次数%d ,移动次数:%d\n",compareTimes,moveTimes);
  312. compareTimes=moveTimes=0;
  313. getch();
  314. printf("正序:\n");
  315. quickSort(l,1,n);
  316. printf("比较次数%d ,移动次数:%d\n",compareTimes,moveTimes);
  317. compareTimes=moveTimes=0;
  318. getch();
  319. printf("逆序:\n");
  320. reverse(l);
  321. quickSort(l,1,n);
  322. printf("比较次数%d ,移动次数:%d\n",compareTimes,moveTimes);
  323. break;
  324. case 6:
  325. //选择排序
  326. selectSort(l);
  327. break;
  328. case 7:
  329. //堆排序
  330. heapSort(l);
  331. getch();
  332. printf("正序:\n");
  333. heapSort(l);
  334. getch();
  335. printf("逆序:\n");
  336. reverse(l);
  337. heapSort(l);
  338. break;
  339. case 8:
  340. //打印数字
  341. print_orderList(l);
  342. break;
  343. case 9:
  344. //逆序输出数字
  345. reverse(l);
  346. break;
  347. case 0:
  348. //退出
  349. exit(0);
  350. default:
  351. printf("您输入的数据有误,请重新输入\n");
  352. break;
  353. }
  354. printf("请按任意键继续\n");
  355. getch();
  356. system("cls");
  357. continue;
  358. }
  359. return 0;
  360. }

发表评论

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

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

相关阅读