堆
堆(heap)通常是一个可以被看做一棵树的数组对象。
堆总是满足下列性质:
-
堆中某个节点的值总是不大于或不小于其父节点的值;
-
堆总是一棵完全二叉树。
堆支持以下的基本操作:
-
build:建立一个空堆;
-
insert:向堆中插入一个新元素;
-
update:将新元素提升使其符合堆的性质;
-
get:获取当前堆顶元素的值;
-
delete:删除堆顶元素;
-
heapify:使删除堆顶元素的堆再次成为堆。
左偏树
左偏树(Leftist Tree)是一种可并堆的实现。
左偏树是一棵二叉树,它的节点除了和二叉树的节点一样具有左右子树指针( left, right)外,还有两个属性,键值和距离(dist)。
它不但要满足堆性质,也同时要满足左偏性质
即任意一个点的左子dist大于等于右子dist
因为它的性质针对每一个节点 所以左偏树的任意一个子树也是左偏树
1 int merge(int x, int y){ 2 if(!x || !y) return x + y;//返回不为空的那个 3 if(node[x].data > node[y].data || (node[x].data == node[y].data && x > y)) swap(x, y); 4 int &l = node[x].ls, &r = node[x].rs; 5 r = merge(r, y); 6 node[r].fa = x; 7 if(node[l].dist < node[r].dist) swap(l, r); 8 node[x].dist = node[r].dist + 1; 9 return x; 10 }
1 void erase(int x){ 2 int l = node[x].ls, r = node[x].rs; 3 node[x].data = -1; 4 node[l].fa = l; 5 node[r].fa = r; 6 merge(l, r); 7 }
斐波那契堆(然鹅并不会