学习笔记--libevent min_heap

libevent采用小根堆管理其timer,所以了解heap的特性是必须的

小根堆的特性为:1完全二叉树

   2子节点的值大于其根结点的值

其实根据这两点,就可以实现小根堆了。完全二叉树决定了如果已知子结点索引child_index,则父结点索引parent_index为(child_index-1)/2,反之

有了这些基础就可以看代码了


/*这个函数的目的是根据hole_index,判断e的插入位置*/

void min_heap_shift_up_(min_heap_t* s, unsigned hole_index, struct event* e)

{

/*找出父结点*/

    unsigned parent = (hole_index - 1) / 2;

/*当索引不为0(即根结点索引时且父结点的值大于e的值时)*/

    while (hole_index && min_heap_elem_greater(s->p[parent], e))

    {

/*记住小根堆的特性,根结点的值必须小于子结点的值,所以当hole_index对应的值小于其父结点的值的时候,父结点下沉,即hole_index上浮*/

(s->p[hole_index] = s->p[parent])->ev_timeout_pos.min_heap_idx = hole_index;

/*hole_index继续上浮*/

hole_index = parent;

parent = (hole_index - 1) / 2;

    }

/*跳出循环是说明条件已不再满足,所以此时可以插入e*/

    (s->p[hole_index] = e)->ev_timeout_pos.min_heap_idx = hole_index;
}

/*与上述过程相反,但实现复杂一点点*/
void min_heap_shift_down_(min_heap_t* s, unsigned hole_index, struct event* e)

{

/*找出子结点*/

    unsigned min_child = 2 * (hole_index + 1);

/*如果没有到最后一个结点*/

    while (min_child <= s->n)

{

/*虽然libevent的实现确实非常强,但是有些代码会让人一下看不出来,源码中有很多类似的实现*/

/*其实下面这句代码相当于(但不是等于,有一个地方s->n),完全二叉树的特性为如果有右子树,那么左子树一定不为空,min_child 的值是代表右子树的值,

因为右子树可能为空,所以需要与堆的长度判断一下,如果相等即有右子树,此时判断条件必为true,即min_child = min_child -1(为左子树的值)

if(s->p[min_child] > s->p[min_child - 1] )

{

min_child -= 1

}

*/

min_child -= min_child == s->n || min_heap_elem_greater(s->p[min_child], s->p[min_child - 1]);

/*如果e的值小于min_child ,跳出循环,已经找到需要插入的地方*/

if (!(min_heap_elem_greater(e, s->p[min_child])))

   break;

/*hole_index下沉*/

(s->p[hole_index] = s->p[min_child])->ev_timeout_pos.min_heap_idx = hole_index;
hole_index = min_child;
min_child = 2 * (hole_index + 1);
}
    (s->p[hole_index] = e)->ev_timeout_pos.min_heap_idx = hole_index;

}




转载于:https://www.cnblogs.com/HaHaJeff/p/10017499.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值