1 #include <cstdio>
 2 #include <iostream>
 3 
 4 using namespace std;
 5 
 6 const int MAX_N = 1000;
 7 
 8 // 用数组来实现二叉树
 9 // 左儿子编号=自己*2 + 1
10 // 右儿子编号=自己*2 + 1
11 int heap[MAX_N],sz=0;
12 
13 // 实现最小堆
14 void push(int x)
15 {
16     // 取最后一个节点的编号,并递增。
17     int i=sz++;
18     // 循环更改所有颠倒序列
19     while(i>0)
20     {
21         int p=(i-1)/2;
22         // 无颠倒序列,退出循环
23         if(heap[p]<=x)
24         {
25             break;
26         }
27         else
28         {
29             heap[i]=heap[p];
30             i=p;
31         }
32     }
33     // 填入新数
34     heap[i]=x;
35 }
36 
37 // 返回最小值(堆顶),然后在堆顶放置堆中最后一个元素
38 // 向下更新,直到有序
39 int pop()
40 {
41     int ret=heap[0];
42     // 记录要提到根节点的数
43     int x=heap[--sz];
44     int i=0;
45     while(2*i+1 < sz)
46     {
47        int a=2*i+1,b=2*i+2;
48        // 如果存在右儿子,且右儿子的值比做儿子小,则记左右儿子中较小者编号a为右儿子的编号
49        if(b<sz && heap[a]>heap[b])
50        {
51            a=b;
52        }
53        // 无逆序,退出循环
54        if(heap[a]>=x)
55        {
56            break;
57        }
58        // 否则将较小数前提,继续向下寻找
59        heap[i]=heap[a];
60        i=a;
61     }
62     // 最后将x写入适当的位置
63     heap[i]=x;
64 
65     return ret;
66 }
67 
68 
69 int main()
70 {
71     push(1);
72     push(5);
73     push(4);
74 
75     cout<<pop()<<endl;
76     push(2);
77     push(7);
78     cout<<pop()<<endl;
79     cout<<pop()<<endl;
80     push(9);
81     for(int i=0;i<3;++i)
82     {
83         cout<<pop()<<endl;
84     }
85     return 0;
86 }

 

posted on 2020-02-05 15:35  带你AK,带你飞  阅读(127)  评论(0编辑  收藏  举报