堆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;//小根堆
有兴趣就在洛谷中位数题解里

 

 

 

posted @ 2020-02-27 22:07  SuccessfulRoad  阅读(186)  评论(0编辑  收藏  举报