堆 在游戏中的运用

* 定时器的应用与原理:

游戏中,活动的状态、游戏数据的保存与加载、BOSS刷新时间等等,都可能会用到定时器。而堆对于定时器的实现有着至关重要的作用。

定时器的工作原理其实不难,就是内部保存多个时间及其回调函数,当系统时间达到我们保存的时间值时,就执行回调函数;从而达到定时工作的效果。同时,判断是否达到指定时间时,只需要判断最早的时间(最早的时间没有达到,更晚的时间肯定不会达到),因此需要对时间列表进行排序。

起初,我设想定时器内部用于保存时间的数据结构是列表;理由是容易理解、实现简单,而且删除节点的时间复杂度为O(1)(对于定时器为说,删除超时时间,而超时时间肯定是在头结点,因此时间复杂度为O(1))。

但是这种做法有明显的不足,因为保存时间列表需要排序,因此插入时间节点的时间复杂度为O(n)。

后来,发现堆在定时器有着非常好的效率;但是堆排序的时间复杂度为O(nlog2n),“XXX,那不是比列表还慢!”。其实不然,我们不需要将整个序列都排好序。前面我已经说过“判断是否达到指定时间时,只需要判断最早的时间”。也就是说我们只需要知道整个序列的最早时间即可。而堆排序刚好有这样的一个名词“小顶堆”。也就是说每次插入时间节点和删除节点,都将序列维持在小顶堆的状态即可。

对于小顶堆,插入节点,重新调整堆结构,其时间复杂度为O(log2n);删除节点,重新调整堆结构,其时间复杂也为O(log2n)。因此整个用小顶堆实现的定时器的时间复杂也就是O(log2n)。比起用列表(list)实现的时间复杂度O(n),效率大大提升。

* 小顶堆讲解:

堆的保存结构是数组,而堆分为大顶堆和小顶堆,满足Key[i]>=Key[2i+1]&&key[i]>=key[2i+2]称为大顶堆,满足 Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]称为小顶堆。也就是说,大顶堆的每一个节点都比子节点大;小顶堆的每一个节点都比子节点小。因此由上述性质可知大顶堆的堆顶的关键字肯定是所有关键字中最大的,小顶堆的堆顶的关键字是所有关键字中最小的。

堆是一棵完全二叉树。下面讲述小顶堆在构造。

插入节点:

扫描二维码关注公众号,回复: 11485949 查看本文章

首先在树的末端插入新结点,新结点与父结点如果新结点大于等于父结点,则不需要改变;否则交换位置。

删除堆顶:

删除堆顶跟删除节点的原理一样,而删除节点跟插入节点刚好相反,删除的节点向下查找两个子节点中最小的节点A替换自己的位置,节点A又相当于删除的节点继续向下查找,直到叶子节点。


猜你喜欢

转载自blog.csdn.net/a374826954/article/details/44154239