acwing 数组模拟堆

acwing 数组模拟堆_第1张图片

 1.简单讲述一下up,down操作

#include
#include
using namespace std;
//数组模拟堆
//堆是一个完全二叉树,所以可以用一个一维数组存储。按照层序遍历存储。
//因为堆是一个完全二叉树,所以某节点i的左儿子即2i,右儿子即2i+1;
//用数组模拟堆的缺点是无法动态改变大小。所以可以用vector代替数组。
//堆分为小根堆和大根堆。有push_heap和pop_heap,插入为上溯操作up,删除为down操作
const int N=1e5+10;
int n,m;
int h[N],cnt ;
//下溯操作,down,跟stl源码剖析中heap的pop_heap差不多
void down(int u)
{
    int t=u;//定义t为答案;
    if(u*2<=cnt&&h[u*2]>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>h[i];
    }
    cnt =n;
    for(int i=n/2;i;i--)  //为什么从n/2开始,因为叶子节点一定满足对堆性质,叶子节点的父节点在完全二叉树表现为n/2
    {                     //所以这样循环就可以构造堆了
        down(i);
    }
    while(m--)
    {
        cout<

 堆中各种操作的具体实现,以及例题。

插入,删除,修改等。还加了堆的映射关系,第k个插入的数的下标。

#include
#include
#include
using namespace std;
const int N=1e5+10;
int h[N],cnt,hp[N],ph[N];
void heap_swap(int a,int b)
{
    swap(ph[hp[a]],ph[hp[b]]); //交换映射关系  ph存储的是第K个插入的数在堆中的位置,hp则相反
    swap(hp[a],hp[b]);
    swap(h[a],h[b]); 
}
void down(int u)
{
    int t=u;
    if(u*2<=cnt&&h[u*2]>n;
    while(n--)
    {
        int k,x;
        string op;
        cin>>op;
        if(op=="I") //插入元素
        {
            cin>>x;
            cnt++;
            m++;
            ph[m]=cnt;hp[cnt]=m; //建立映射关系
            h[cnt]=x;
            up(cnt);
        }
        else if(op=="PM") cout<>k;
            k=ph[k];
            heap_swap(k,cnt);
            cnt--;
            up(k);
            down(k);
        }
        else    //修改第K个插入的数
        {
            cin>>k>>x;
            k=ph[k]; //第K个数的下标
            h[k]=x;
            up(k);
            down(k);
        }
    }

    
    return 0;
}

你可能感兴趣的:(acwing算法学习,数据结构,c++,开发语言,数据结构)