[NHZXOI2017]【2016NOIP】堆复习

来源:互联网 发布:wnacg新域名wnacg.net 编辑:程序博客网 时间:2024/06/06 10:15

  堆是一种数据结构,分为两类——最大堆和最小堆(按我目前所学)

主要的操作有插入和删除,维护的方式有上移和下移。

我规定:

  插入:Insert(int num);

  删除:delete_top();(删除根节点);

  上移:sift_up(int i);

  下移:sift_dow(int i);

  堆:h[i]

各个子程序的代码:

插入:插入到尾部+上移

void Insert(int num){h[0]++;h[h[0]]=num;sift_up(h[0]);}


删除:删除堆顶,把最后的一个数放上来+下移

void delete_top(){h[1]=h[h[0]]; h[h[0]]=0;h[0]--;sift_down(1);}

上移:

void sift_up(int i){bool done=false;while (i!=1 && !done){if (h[i]>h[i/2]) swap(h[i],h[i/2]); else done=true;i/=2;}}


下移:

void sift_down(int i){bool done=false;while (i*2<=n && !done){i*=2;if (i+1<n && h[i]<h[i+1]) i++;if (h[i/2]<h[i]) swap(h[i],h[i/2]);  else done=true;}}

建堆方式:

①一个一个地插入到尾部+上移。

②在原有的一列数的基础上,对第1~n/2个数进行下移。


总结:个人认为还是规范个人写法,形成个人风格比较好。之前学习是看的资料比较多,又没吃透,导致程序码的超级丑。

堆其实不是很难,却很实用。多用于模拟、搜索、动态规划的优化之中。代码简单规范。初学者建议可以背下代码,理解就是自然而然的事情了。

1 0