二分堆数据结构详解
本文介绍了二分堆(binary heap)的基本实现原理及其在图论算法中的应用——映射二分堆(mapped binary heap)。主要讲解了如何进行元素的插入、获取及删除操作,并提供了关键代码示例。

//二分堆(binary)

//可插入,获取并删除最小(最大)元素,复杂度均O(logn)

//可更改元素类型,修改比较符号或换成比较函数

#define MAXN 10000

#define _cp(a,b) ((a)<(b))

typedef int elem_t;

struct heap{

elem_t h[MAXN];

int n,p,c;

void init(){n=0;}

void ins(elem_t e){

for (p=++n;p>1&&_cp(e,h[p>>1]);h[p]=h[p>>1],p>>=1);

h[p]=e;

}

int del(elem_t& e){

if (!n) return 0;

for (e=h[p=1],c=2;c<n&&_cp(h[c+=(c<n-1&&_cp(h[c+1],h[c]))],h[n]);h[p]=h[c],p=c,c<<=1);

h[p]=h[n--];return 1;

}

};

//映射二分堆(mapped)

//可插入,获取并删除任意元素,复杂度均O(logn)

//插入时提供一个索引值,删除时按该索引删除,获取并删除最小元素时一起获得该索引

//索引值范围0..MAXN-1,不能重复,不负责维护索引的唯一性,不在此返回请另外映射

//主要用于图论算法,该索引值可以是节点的下标

//可更改元素类型,修改比较符号或换成比较函数

#define MAXN 10000

#define _cp(a,b) ((a)<(b))

typedef int elem_t;

struct heap{

elem_t h[MAXN];

int ind[MAXN],map[MAXN],n,p,c;

void init(){n=0;}

void ins(int i,elem_t e){

for (p=++n;p>1&&_cp(e,h[p>>1]);h[map[ind[p]=ind[p>>1]]=p]=h[p>>1],p>>=1);

h[map[ind[p]=i]=p]=e;

}

int del(int i,elem_t& e){

i=map[i];if (i<1||i>n) return 0;

for (e=h[p=i];p>1;h[map[ind[p]=ind[p>>1]]=p]=h[p>>1],p>>=1);

for (c=2;c<n&&_cp(h[c+=(c<n-1&&_cp(h[c+1],h[c]))],h[n]);h[map[ind[p]=ind[c]]=p]=h[c],p=c,c<<=1);

h[map[ind[p]=ind[n]]=p]=h[n];n--;return 1;

}

int delmin(int& i,elem_t& e){

if (n<1) return 0;i=ind[1];

for (e=h[p=1],c=2;c<n&&_cp(h[c+=(c<n-1&&_cp(h[c+1],h[c]))],h[n]);h[map[ind[p]=ind[c]]=p]=h[c],p=c,c<<=1);

h[map[ind[p]=ind[n]]=p]=h[n];n--;return 1;

}

};

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值