Linux(服务器编程):31---高性能定时器之时间堆

一、时间堆概述

  • 前文几篇文章(https://blog.csdn.net/qq_41453285/article/details/103719025https://blog.csdn.net/qq_41453285/article/details/103733141)介绍的定时方案都是以固定的频率调用心搏函数tick,并在其中依次检测到期的时间器,然后指定到期定时器上的回调函数
  • 文本设计定时器的另一种思路:
    • 1.将所有定时器中超时时间最小的一个定时器的超时值作为心搏间隔。这样,一旦心搏函数tick被调用,超时时间最小的定时器必然到期,我们就可以在tick函数中处理该定时器
    • 2.然后再次从剩余的定时器中找出超时时间最小的一个,并将这段最小时间设置为下一次心搏间隔
    • 3.如此反复,就实现了较为精确的定时
  • 最小堆是实现上面定时器思想的最佳选择方案

二、最小堆

最小堆的插入

  • 最小堆的插入操作就是在最小堆最后插入一个节点,然后重新调整最小堆的结构
  • 插入原理:
    • 1.先将添加的新元素放在最小堆的最后一个位置
    • 2.然后新元素与父节点进行比较(如果有父节点的话)。如果比父节点的值大,那么就结束插入操作,插入操作也到此为止;如果比父节点的值小,那么就与父节点进行位置交换
    • 3.重复步骤2,直到无父节点或者比父节点的值大,停止插入操作
  • 演示案例:
    • 例如在上面的最小堆中插入元素14

最小堆的删除

  • 最小堆的删除操作就是删除根节点,然后重新调整最小堆的结构
  • 删除原理:
    • 1.将原根节点处删除
    • 2.将最小堆的最后一个节点移动到根节点
    • 3.然后判断子节点是否有比自己的值小,如果小,那么就与子节点进行交换(如果两个子节点都比自己的值小,那么就挑最小的进行交换)
    • 4.重复步骤3,直至子节点的值都比自己大,结束删除操作
  • 演示案例:
    • 例如在上面的最小堆中删除一个元素

最小堆的初始化

三、最小堆的数组表示

  • 我们可以将最小堆用数组来表示。并且有如下规则(若数组上一个元素的索引为i):
    • 左子节点的索引为2i+1、右子节点的索引为2i+2
    • 父节点的索引为(i-1)/2
  • 例如下面一个最小堆的数组表示形式如下:

  • 数组表示的优点:与链表表示相比,数组表示更节省空间、堆的插入、删除操作比较容易

四、代码设计

待续

发布了1300 篇原创文章 · 获赞 827 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/qq_41453285/article/details/103733710