堆1
堆(大顶(根)堆,小顶(根)堆)是支持如下操作的动态集合:(完全二叉树表示)
插入元素:将元素插入堆中
删除堆顶:删除堆中优先级最大(最小)的元素
查询堆顶:返回堆中优先级最大(最小)的元素
//完美二叉树:每层都填满
堆还有,配对堆,斐波那契堆
大顶堆:父亲节点的值大于儿子
小顶堆:儿子大于父亲
二叉树可用数组存储:根节点i,左儿子2*i,右儿子2*i+1;
代码实现:
int size;//记录堆中的元素 int heap[1024];//堆中元素1023个 void push(int x)//插入元素 { ++size; heap[size]=x; for(int i=size;i>1&&heap[i]>heap[i/2];i/=2)//比较插入元素与父亲的值 swap(heap[i],heap[i/2]);//交换值,直到满足堆 }//Olog(n) 删除堆顶时,自上而下地进行交换 void adjust(int i) { int largest=i;//最后一个节点与根节点交换顺序 if(i*2<size&&heap[i*2]>heap[largest]) largest=i*2' if(i*2+1<=size&&heap[i*2+1]>heap[largest]) largest=i*2+1; if(largest!=i){ swap(heap[i],heap[largest]); i=largest; adjust(i); } } void pop() { heap[1]=heap[size]; --size; adjust(1); }//Olog(n) 如果heap数组里已经有了n个元素,要将这些元素组成堆 的形式,有两种方法: 最简单的方法是将它们看成一个一个的元素,依次插入堆中,时间复杂度(nlog(n)) 另一种:从底向上对每个元素依次执行adjus,O(n) void build(){ for(int i=size/2;i>=1;i--) adjust(i); }
P1168 中位数
根据中位数性质,即较小数的最大值,较大数的最小值;
可以用两个堆(大顶堆(T,较小部分),小顶堆(S,较大部分))来维护,可以设|S|<=|T|<=|S|+1;假设||S|-|T||<2;等于2时,若S元素多,将S的根给T,删除S的根,维护S堆,同理T;洛谷题解真是人才辈出,好吧,是我见识短浅。可以用stl的优先队列来维护堆
作者: 肖恩Sean 更新时间: 2018-05-03 21:25 在Ta的博客查看
priority_queue<int,vector<int> > q1;//大根堆
priority_queue<int,vector<int>,greater<int> > q2;//小根堆
有兴趣就在洛谷中位数题解里