今天打算学习左偏堆,可是想起来自己二叉堆都没有看懂,于是就跑去回顾二叉堆了。发现以前看不懂的二叉堆,今天看起来特简单,随手就写好了一个堆了。

  简单的说一下我对二叉堆操作的理解。我不从底层函数说上去,相反,我打算从实现来解释底层函数的构造,以大堆为例。

  其实操作都很简单,对于push函数,因为堆是一棵严格的完全二叉树,所以我们直接在队列的尾端插入新增加的元素。然后就将这个元素不停的跟他的父节点进行比较,如果这个元素更大就跟父节点交换,否则就退出上推更新这个操作。对于pop的操作也是差不多的,我们可以将出堆的元素的位置用最底的元素替换。然后就是将这个替换上堆顶的元素下推。对于当前这个元素的位置,如果左儿子比右儿子大,就用左儿子跟当前元素比较,如果左儿子比较大,就把左儿子交换上去。反之亦然。

通过简单测试的二叉堆代码如下:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <queue>
 6 
 7 using namespace std;
 8 
 9 const int Q = 111111;
10 template<class T>
11 struct PriQ {
12     T q[Q];
13     int sz;
14     void clear() { sz = 0;}
15     void up(int k) {
16         while (k > 1) {
17             if (q[k] < q[k >> 1]) swap(q[k >> 1], q[k]);
18             else return ;
19             k >>= 1;
20         }
21     }
22     void push(T x) {
23         q[++sz] = x;
24         up(sz);
25     }
26     void down(int k) {
27         while ((k << 1) <= sz) {
28             if ((k << 1) == sz || q[k << 1] < q[k << 1 | 1]) {
29                 if (q[k << 1] < q[k]) swap(q[k], q[k << 1]);
30                 else return ;
31                 k = k << 1;
32             } else {
33                 if (q[k << 1 | 1] < q[k]) swap(q[k], q[k << 1 | 1]);
34                 else return ;
35                 k = k << 1 | 1;
36             }
37         }
38     }
39     void pop() {
40         q[1] = q[sz];
41         sz--;
42         down(1);
43     }
44     T top() { return q[1];}
45     int size() { return sz;}
46 } ;
47 PriQ<int> pq;
View Code

相关文章:

  • 2021-12-01
  • 2022-12-23
  • 2021-12-31
  • 2022-12-23
  • 2022-12-23
  • 2021-10-23
  • 2022-01-14
  • 2021-12-31
猜你喜欢
  • 2021-09-14
  • 2022-12-23
  • 2022-12-23
  • 2022-01-05
  • 2022-12-23
  • 2021-05-23
相关资源
相似解决方案