堆的插入与删除(最大堆)

 堆的插入:
 这里以最大堆为例子,先将要插入的元素放在堆的末尾,然后将其与父节点比较,如果比父节点大,那么就与父节点交换。

重复此操作,这里有个技巧,可以在堆的上面设一个很大的元素,称为哨兵,这样即使是到了堆顶也会自动停下。不会出现超范围的问题。

堆的删除:

堆的删除指的是删除堆的最大元素,也就是堆顶。删除完之后将堆尾的元素拿到堆首,然后再与两个孩子中的较大的元素进行比较,如果小,则交换,重复此步骤,直到比它们都大或者没有孩子的时候。

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=1005;
struct heap   //最大堆
{
    int data[maxn];
    int Size;
};
heap h;
int n;
void init() //初始化
{
    h.Size=0;
    h.data[0]=INF; //哨兵
}
void Insert(int data) //插入
{
    h.data[++h.Size]=data;
    int i=h.Size;
    while (data>h.data[i/2])
    {
        h.data[i]=h.data[i/2];
        i/=2;
    }
    h.data[i]=data;

}
bool IsEmpty() //判断是否为空
{
    if(h.Size==0)
        return true;
    else
        return false;
}
int DeleteMax () //删除栈顶元素
{
    if(IsEmpty())
        return -1;
    int parent,child;
    int temp=h.data[1];
    int data=h.data[h.Size--];
    for (parent=1;parent*2<=h.Size;parent=child)
    {
        child=parent*2;
        if((child!=h.Size)&&h.data[child]<h.data[child+1])
                     child+=1;
        if(h.data[child]>data)
            h.data[parent]=h.data[child];
        else
            break;
    }
    h.data[parent]=data;
    return temp;
}
int main()
{
    scanf("%d",&n);
    init();
    for (int i=0;i<n;i++)
    {
        int m;
        scanf("%d",&m);
        Insert(m);
    }
    while (DeleteMax()!=-1)
    {
        for (int i=1;i<=h.Size;i++)
        printf("%d ",h.data[i]);
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41410799/article/details/81431147
今日推荐