fork download
  1. // heap-ki
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5.  
  6. #define height 4
  7. #define MAX (1<<height) //ビットシフト演算 2^height と同じ
  8.  
  9. int t[MAX+1]; //配列外アクセス防止のためのダミーで+1
  10. int sz = 0;
  11.  
  12. void swap(int *x, int *y){
  13. int tmp = *x;
  14. *x = *y;
  15. *y = tmp;
  16. }
  17.  
  18. void initTree(int n){
  19. int i;
  20. for(i=0;i<MAX;i++){
  21. t[i] = -1;
  22. }
  23. }
  24.  
  25. void printA(){
  26. int i;
  27. for(i=1;i<=sz;i++) printf("%d ",t[i]);
  28. printf("\n");
  29. }
  30.  
  31. void printT(int i){
  32. int x = i;
  33. while(x/2!=0){
  34. printf(" ");
  35. x/=2;
  36. }
  37. printf("%d\n",t[i]);
  38. }
  39.  
  40. int goP(int i){
  41. if(i/2 == 0) return 0;
  42. else return i/2;
  43. }
  44.  
  45. int goL(int i){
  46. if(2*i >= MAX) return 0;
  47. else return 2*i;
  48. }
  49.  
  50. int goR(int i){
  51. if(2*i+1 >= MAX) return 0;
  52. else return 2*i+1;
  53. }
  54.  
  55. void preOrder(int i){
  56. if(t[i] == -1) return;
  57. printT(i);
  58. preOrder(goL(i));
  59. preOrder(goR(i));
  60. }
  61.  
  62. void inOrder(int i){
  63. if(t[i] == -1) return;
  64. inOrder(goL(i));
  65. printT(i);
  66. inOrder(goR(i));
  67. }
  68.  
  69. void postOrder(int i){
  70. if(t[i] == -1) return;
  71. postOrder(goL(i));
  72. postOrder(goR(i));
  73. printT(i);
  74. }
  75.  
  76. void insBT(int x){
  77. int k,i = 1;
  78. for(k=0;k<height;k++){
  79. if(t[i]==-1){
  80. t[i] = x;
  81. sz++;
  82. return;
  83. }
  84. if(x < t[i]) i = goL(i);
  85. else i = goR(i);
  86. }
  87. printf("Error : too high -> %d\n",x);
  88. }
  89.  
  90. //先頭の要素を取り出す
  91. //ダウンヒープ
  92. int popHeap(){
  93. // 取り出して
  94. // 末尾の要素を根に持ってきて
  95. // 子のうちの大きい方と比較
  96. // 子の方が大きかったら交換
  97. // をHeapが完成するまで繰り返す
  98. // 事前学習資料のP.56~60
  99. int a,i,j,k=1;
  100.  
  101. a=t[1];
  102. t[1]=-1;
  103.  
  104. swap(&t[1],&t[sz]);
  105. sz--;
  106.  
  107. while(1){
  108. i=k*2;
  109. j=k*2+1;
  110.  
  111. if(t[i]>t[j] && t[i]>t[k]){
  112. swap(&t[i],&t[k]);
  113. k=i;
  114. }
  115. else if(t[i]<t[j] && t[j]>t[k]){
  116. swap(&t[j],&t[k]);
  117. k=i;
  118. }
  119. else if(t[k]>t[i] && t[k]>t[j]){
  120. break;
  121. }
  122. else if(i>sz || j>sz){
  123. break;
  124. }
  125. }
  126.  
  127. return a;
  128.  
  129.  
  130. }
  131.  
  132. //末尾に要素を追加する
  133. //アップヒープ
  134. void pushHeap(int x){
  135. // 末尾に追加
  136. // 親と比較して、子の方が大きかったら交換
  137. // をHeapが完成するまで繰り返す
  138. int i;
  139. sz++;
  140. i = sz;
  141. t[i] = x;
  142.  
  143. while(i>1&&t[i]>t[i/2]){
  144. swap(&t[i],&t[i/2]);
  145. i=i/2;
  146. }
  147. }
  148.  
  149. int main(void){
  150. int i,n;
  151. scanf("%d",&n);
  152. // 木の初期化
  153. initTree(n);
  154. for(i=0;i<n;i++){
  155. scanf("%d",&t[i+1]);
  156. }
  157. sz = n;
  158. // 中間順で表示
  159. inOrder(1);
  160.  
  161. // pop
  162. int a=popHeap();
  163. printf("pop : %d\n",a);
  164. inOrder(1);
  165.  
  166. a = popHeap();
  167. printf("pop : %d\n",a);
  168.  
  169. inOrder(1);
  170.  
  171. printf("push : 100\n");
  172. pushHeap(100);
  173. inOrder(1);
  174.  
  175. printf("push : 30\n");
  176. pushHeap(30);
  177. inOrder(1);
  178. return 0;
  179. }
  180.  
Success #stdin #stdout 0.01s 5316KB
stdin
12
89 34 55 13 16 21 32 2 3 4 5 8
stdout
      2
    13
      3
  34
      4
    16
      5
89
      8
    21
  55
    32
pop : 89
      2
    13
      3
  34
      4
    16
      5
55
    21
  8
    32
pop : 55
      2
    13
      3
  16
      4
    5
34
    21
  8
    32
push : 100
      2
    13
      3
  34
      4
    16
      5
100
    21
  8
    32
push : 30
      2
    13
      3
  34
      4
    16
      5
100
      21
    8
  30
    32