【1098】Insertion or Heap Sort (25 分)

举报
野猪佩奇996 发表于 2022/01/24 00:43:15 2022/01/24
【摘要】 #include<iostream>#include<stdio.h>#include<stdlib.h>#include<math.h>#include<string.h>#include<algorithm> #include<map>#inclu...

  
  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<math.h>
  5. #include<string.h>
  6. #include<algorithm>
  7. #include<map>
  8. #include<vector>
  9. #include<queue>
  10. using namespace std;
  11. //和A1089类似,注意堆排序
  12. const int N=111;
  13. int origin[N],tempOri[N],changed[N]; //原始数组、原始数组备份、目标数组
  14. int n; //元素个数
  15. bool isSame(int A[],int B[]){ //判断数组A和数组B是否相同
  16. for(int i=1;i<=n;i++){
  17. if(A[i]!=B[i]) return false;
  18. }
  19. return true;
  20. }
  21. void showArray(int A[]){ //输出数组
  22. for(int i=1;i<=n;i++){
  23. printf("%d",A[i]);
  24. if(i<n) printf(" ");
  25. }
  26. printf("\n");
  27. }
  28. bool insertSort(){ //插入排序
  29. bool flag=false; //记录是否存在数组中间步骤与changed数组相同
  30. for(int i=2;i<=n;i++) { //进行n-1趟排序
  31. if(i != 2 && isSame(tempOri,changed)){
  32. flag=true; //中间步骤与目标相同,且不是初始序列
  33. }
  34. //插入部分直接用sort代替
  35. sort(tempOri,tempOri+i+1);//注意要加上1,因为后面要输出下一步序列
  36. if(flag == true){
  37. return true; //如果flag为true,则说明已达到目标数组,返回true
  38. }
  39. }
  40. return false; //无法达到目标数组,返回false
  41. }
  42. //对heap数组在[low,high]范围进行调整
  43. //其中为欲调整结点的数组下标,high一般为堆的最后一个元素的数组下标
  44. void downAdjust(int low,int high){
  45. int i=low,j=i*2; //i为欲调整的结点,j为其左孩子结点
  46. while(j <= high) { //存在孩子结点
  47. //如果右孩子结点存在,且右孩子结点的值大于左孩子结点
  48. if(j+1 <=high && tempOri[j+1] > tempOri[j]){
  49. j=j+1; //让j存储右孩子结点下标
  50. }
  51. //如果孩子结点(此处为右孩子)中最大的权值比父亲结点大
  52. if(tempOri[j] > tempOri[i]){
  53. swap(tempOri[j],tempOri[i]); //交换最大权值的孩子结点与父亲结点
  54. i=j; //令i为j,令j为i的!!左!!孩子结点,进入下一层
  55. j=i*2;
  56. }else {
  57. break; //孩子结点的权值均比父亲结点的小,调整结束
  58. }
  59. }
  60. }
  61. void heapSort(){ //堆排序
  62. bool flag=false;
  63. for(int i=n/2;i>=1;i--){
  64. downAdjust(i,n); //建堆
  65. }
  66. for(int i=n;i>1;i--){
  67. if(i != n && isSame(tempOri,changed)){
  68. flag = true; //中间步骤与目标相同,且不是初始序列
  69. }
  70. swap(tempOri[i],tempOri[1]); //交换heap[i]与堆顶
  71. downAdjust(1,i-1); //调整堆顶
  72. if(flag == true){
  73. showArray(tempOri); //已达到目标数组,返回true
  74. return;
  75. }
  76. }
  77. }
  78. int main(){
  79. scanf("%d",&n);
  80. for(int i=1;i<=n;i++){
  81. scanf("%d",&origin[i]); //输入起始数组
  82. tempOri[i]=origin[i]; //tempOri数组为备份,排序在tempOri上进行
  83. }
  84. for(int i=1; i<=n;i++){
  85. scanf("%d",&changed[i]); //目标数组
  86. }
  87. if(insertSort()){ //如果插入排序中找到目标数组
  88. printf("Insertion Sort\n");
  89. showArray(tempOri);
  90. }else{ //到达此时一定是堆排序
  91. printf("Heap Sort\n");
  92. for(int i=1;i<=n;i++){
  93. tempOri[i]=origin[i]; //还原tempOri数组
  94. }
  95. heapSort(); //堆排序
  96. }
  97. system("pause");
  98. return 0;
  99. }

 

文章来源: andyguo.blog.csdn.net,作者:山顶夕景,版权归原作者所有,如需转载,请联系作者。

原文链接:andyguo.blog.csdn.net/article/details/99556455

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。