博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
堆(heap)——C++实现
阅读量:6535 次
发布时间:2019-06-24

本文共 3175 字,大约阅读时间需要 10 分钟。

   优先队列从名字我们就可以猜到,其与队列之间存在一定的练习,优先队列与队列一样主要是入队和出队两个操作。但是优先队列与队列的不同之处在于,优先队列会将优先级高的先出队,这在很多情况下非常有用。例如,Windows的MFC是基于消息的响应的机制,内部管理着一个消息队列,计算机不断从消息队列中抓取消息进行响应,那么系统的消息和应用软件的消息优先级必然不同,我们需要优先响应系统的消息,那么优先队列就显示它强大的功能。

  堆的实现我们可以通过一个表,或者一个二叉树都可以实现。如果通过一个表实现,入队很方便,但是出队,必须遍历一遍表找到优先级最高的那个,需要花费O(N)的时间,效率太低。对于二叉树来说入队和出队都是O(logN)的时间复杂度,但是二叉树的频繁删除会导致树向右边倾斜,当然我们可以通过平衡树来解决这个问题,但是对于优先队列来说最简单的方式是通过二叉堆实现。

  二叉堆的实质是一个数组,只是我们用完全二叉树的形式将其表述出来,完全二叉树与不完全二叉树的区别如下图:

 

  数组的第一位我们空出来是为了去满足二叉堆的性质:设某元素所处于数组中的位置为i,那么他的左儿子的位置使2*i,他的父元素的位置在i/2;

  因为对于堆来说插入比删除要频繁,因此将优先级最高的放在第一个,因为删除比插入麻烦的多。

  以下是例程,用vector实现:

1 /************************************************************************/ 2 /* 堆的实现                                                                     */ 3 /************************************************************************/ 4 #include
5 namespace stl 6 { 7 template
8 class Heap 9 {10 public:11 /************************************************************************/12 /*构造函数*/13 Heap(int capacity = 100)14 :size(0) //堆中包含数据个数15 {16 H.resize(capacity);17 }18 19 ~Heap()20 {21 }22 23 bool isEmpty()24 {25 return size == 0;26 }27 28 void makeEmpty()29 {30 size = 0;31 for (auto it = H.begin(); it != H.end(); it++)32 {33 H.erase(it);34 }35 }36 /************************************************************************/37 /*插入函数 */38 void insert(const T & x)39 {40 //如果vector中已经存满了,重新分为大小,数组首地址不存数据41 if (size == H.size() -1)42 {43 H.resize(2*size);44 }45 //size大小加一46 for (int current = ++size; current > 1 && H[current/2] > x; current /= 2)47 {48 H[current] = H[current/2];49 }50 //找到空位将x插入51 H[current] = x;52 }53 54 /*删除函数*/55 T deleteMin()56 {57 if (isEmpty())58 {59 throw();60 }61 int current, child;62 T returnVal = H[1];63 T lastElement = H[size--]; //将最后一个值保存下来,删除一个元素所以自减运算64 for (current = 1; 2 * current > size; current = child)65 {66 child = 2 * current;67 //防止访问越界68 if (child != size && H[2 * current] > H[2 * current + 1]) 69 {70 ++child;71 }72 //比较子较小的儿子与最后一个值的大小,如果儿子较小用儿子上滤,否则跳出循环73 if (H[child] < lastElement)74 {75 H[current] = H[child];76 }77 else78 {79 break;80 }81 }82 H[current] = lastElement;83 return returnVal;84 }85 86 private:87 std::vector
H;88 int size;89 };90 }

 

转载于:https://www.cnblogs.com/liuteng/p/6048322.html

你可能感兴趣的文章
简单登录系统
查看>>
51CTO学院四周年# 每天进步一点点”;
查看>>
maven中对jsp预编译方法
查看>>
abr-summary 和asbr-summary命令中的not-advertise参数
查看>>
数据库隔离级别
查看>>
小型企业局域网免费上网行为管理方案
查看>>
【研究任务】热迁移方式——pre-copy、post-copy和x-multifd
查看>>
Anaconda3启动ipython的几种方式
查看>>
Windows下安装Scrapy方法及常见安装问题总结——Scrapy安装教程
查看>>
十六、lvm、磁盘故障小案例
查看>>
技本功丨请带上纸笔刷着看:解读MySQL执行计划的type列和extra列
查看>>
nginx基础
查看>>
MySQL主从复制虽好,能完美解决数据库单点问题吗?
查看>>
工作态度的重要性
查看>>
如何简单的将pdf文件转换成html超文本标记语言
查看>>
UI设计中有哪些常见问题需要避免?
查看>>
Docker 的基本概念和框架
查看>>
httpd.conf文件详解(转)
查看>>
系统设计(系列二)--现上问题整理(云崩溃和服务不可用)
查看>>
eclipse 导入自定义jar包
查看>>