二分堆(binary)
2010-11-19 11:01
//二分堆(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; } }; //映射二分堆 //可插入,获取并删除任意元素,复杂度均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; } }; |