首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

最小堆定时器

最小堆定时器

一、前言相信大家在网络编程过程中或者查看开源代码中,总是会遇到一些定时器的功能,今天介绍一种常用的定时器,最小堆定时器;二、最小堆

树的基本概念

完全二叉树:若二叉树的深度为h,则除第h层外,其他层的结点全部达到最大值,且第h层的所有结点都集中在左子树。

满二叉树:满二叉树是一种特殊的的完全二叉树,所有层的结点都是最大值。

最小堆定义

堆是一颗完全二叉树;

堆中的某个结点的值总是大于等于(最大堆)或小于等于(最小堆)其孩子结点的值。

堆中每个结点的子树都是堆树

子节点都小于父节点

数组中的任意一个位置i上的元素,其左子节点在位置2i+1上,其右子节点在2i+2上,其父节点则在(i-1)/2上;三、案例一个数组数据为:21,24,31,65,26

以上就是一个简单的最小堆;这里,参考了网上代码,给大家展示一下代码:

time_heap.h

#pragma once

#include

#include

#include

#include

constintBUFFER_SIZE=64;

classheap_timer;

//用户数据,绑定socket和定时器

structclient_data

{

sockaddr_inaddress;

intsockfd;

charbuf[BUFFER_SIZE];

heap_timer*timer;

};

//定时器

classheap_timer

{

public:

heap_timer(intdelay)

{

expire=time(NULL)+delay;

}

public:

time_texpire;//定时器生效绝对时间

void(*cb_func)(client_data*);//定时器回调函数

client_data*user_data;//客户端数据

};

//时间堆

classtime_heap

{

public:

//构造之一:初始化一个大小为cap的空堆

time_heap(intcap);

//构造之二:用已用数组来初始化堆

time_heap(heap_timer**init_array,intsize,intcapacity);

//销毁时间堆

~time_heap();

//添加定时器timer

intadd_timer(heap_timer*timer);

//删除定时器timer

voiddel_timer(heap_timer*timer);

//获得顶部的定时器

heap_timer*top()const;

//删除顶部的定时器

voidpop_timer();

//心跳函数

voidtick();

//堆是否为空

boolempty()const;

//最小堆的下操作,

//确保堆数组中认第hole个节点作为根的子树拥有最小堆性质

voidpercolate_down(inthole);

//将堆数组容量扩大1倍

voidresize();

private:

heap_timer**array;//堆数组

intcapacity;//堆数组的空量

intcur_size;//堆数组当前包含元素个数

};

time_heap.cpp

#include "time_heap.h"

time_heap::time_heap(intcap):capacity(cap),cur_size()

{

//创建数组

array=newheap_timer*[capacity];

if(!array)

{

fprintf(stderr,"init heap faild");

return;

}

for(inti=;i

{

array[i]=NULL;

}

}

time_heap::time_heap(heap_timer**init_array,intsize,intcapacity):

capacity(capacity),cur_size(size)

{

if(capacity

{

fprintf(stderr,"init ");

}

//创建堆数组

array=newheap_timer*[capacity];

if(!array)

{

fprintf(stderr,"init heap_timer failed");

return;

}

for(inti=;i

{

array[i]=NULL;

}

//初始化堆数组

if(size!=)

{

for(inti=;i

array[i]=init_array[i];

for(inti=(cur_size-1)/2;i>=;--i)

{

percolate_down(i);

}

}

}

time_heap::~time_heap()

{

for(inti=;i

{

deletearray[i];

}

delete[]array;

}

inttime_heap::add_timer(heap_timer*timer)

{

if(!timer)

return-1;

//如果堆数组不够大,在扩充一倍

if(cur_size>=capacity)

{

resize();

}

////新插入一个元素,当前堆大小加1, hole是新建空穴的位置

inthole=cur_size++;

intparent=;

//对从空穴到根节点的路径上的所有节点执行上虑操作

for(;hole>;hole=parent)

{

parent=(hole-1)/2;

if(array[parent]->expireexpire)

{

break;

}

array[hole]=array[parent];

}

array[hole]=timer;

return;

}

voidtime_heap::del_timer(heap_timer*timer)

{

if(!timer)

return;

timer->cb_func=NULL;

}

heap_timer*time_heap::top()const

{

if(empty())

{

returnNULL;

}

returnarray[];

}

voidtime_heap::pop_timer()

{

if(empty())

{

return;

}

if(array[])

{

deletearray[];

//将原来的堆顶元素替换为堆数组中最后一个元素

array[]=array[--cur_size];

//对新的堆顶元素执行以下操作

percolate_down();

}

}

voidtime_heap::tick()

{

heap_timer*tmp=array[];

time_tcur=time(NULL);

//循环处理定时器

while(!empty())

{

if(!tmp)

{

break;

}

//如果堆顶定时没有到期,则退出循环

if(tmp->expire>cur)

{

break;

}

//否则执行堆顶定时器中的回调函数

if(array[]->cb_func)

{

array[]->cb_func(array[]->user_data);

}

//删除堆顶元素,同时生成新的堆顶定时器

pop_timer();

tmp=array[];

}

}

voidtime_heap::percolate_down(inthole)

{

heap_timer*tmp=array[hole];

intchild=;

for(;((hole*2)+1)

{

child=hole*2+1;

if(childexpire

array[child]->expire)

{

++child;

}

if(array[child]->expireexpire)

{

array[hole]=array[child];

}

else

{

/* code */

break;

}

}

array[hole]=tmp;

}

voidtime_heap::resize()

{

heap_timer**tmp=newheap_timer*[2*capacity];

for(inti=;i

{

tmp[i]=NULL;

}

if(!tmp)

{

fprintf(stderr,"resize() faild");

return;

}

capacity=2*capacity;

for(inti=;i

{

tmp[i]=array[i];

}

delete[]array;

array=tmp;

}

booltime_heap::empty()const

{

if(empty())

returnNULL;

returnarray[];

}

想了解学习更多C++后台服务器方面的知识,请关注:微信公众号:====C++后台服务器开发====

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200301A05ZZC00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券