首页 > 代码库 > 堆的基本操作

堆的基本操作

大顶堆

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<queue>
#include<algorithm>

using namespace std;
const int maxn=10007;

int heap[maxn];
int n;
///堆调整
void AdjustHeap(int root)
{
    int lchild=2*root+1;
    int rchild=2*root+2;
    int temp=heap[root];

    while(lchild<n)
    {
        if(rchild<n && heap[rchild]>heap[lchild])
            lchild++;
        if(heap[lchild]<=temp)
            break;
        heap[root]=heap[lchild];
        root=lchild;
        lchild=2*root+1;
        rchild=2*root+2;
    }
    heap[root]=temp;
}

/*插入函数,  将要插入的数字首先加入到该二叉树最后的一个节点,
自底而上调整*/
void InsertHeap(int num)
{
    int child=n;
    int root=(child-1)/2;
    heap[child]=num;

    while(root>=0 && child!=0)
    {
        if(heap[root]>num)
            break;
        heap[child]=heap[root];
        child=root;
        root=(child-1)/2;
    }
    heap[child]=num;
    n++;
}

/*删除函数,对于最小堆和最大堆而言,删除是针对于根节点而言。
将二叉树的最后一个节点替换到根节点,然后自顶向下调整。*/
void DeleteHeap()
{
    heap[0]=heap[n-1];
    n--;
    AdjustHeap(0);
}

void BuildHeap()
{
    for(int i=(n-2)/2; i>=0; i--)
        AdjustHeap(i);
}
void Display()
{
    for(int i=0; i<n; i++)
        printf("%d%c", heap[i], i==n-1?\n: );
}

int main()
{
    while(~scanf("%d", &n))
    {
        for(int i=0; i<n; i++)
            scanf("%d", &heap[i]);
        BuildHeap();
        Display();

        int a;
        scanf("%d", &a);
        InsertHeap(a);
        Display();

        DeleteHeap();
        Display();
    }
    return 0;
}
/*
6
16 7 3 20 17 8
30
*/

小顶堆

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<queue>
#include<algorithm>

using namespace std;
const int maxn=10007;

int heap[maxn];
int n;
///堆调整
void AdjustHeap(int root)
{
    int lchild=2*root+1;
    int rchild=2*root+2;
    int temp=heap[root];

    while(lchild<n)
    {
        if(rchild<n && heap[rchild]<heap[lchild])
            lchild++;
        if(heap[lchild]>=temp)
            break;
        heap[root]=heap[lchild];
        root=lchild;
        lchild=2*root+1;
        rchild=2*root+2;
    }
    heap[root]=temp;
}

/*插入函数,  将要插入的数字首先加入到该二叉树最后的一个节点,
自底而上调整*/
void InsertHeap(int num)
{
    int child=n;
    int root=(child-1)/2;
    heap[child]=num;

    while(root>=0 && child!=0)
    {
        if(heap[root] <= num)
            break;
        heap[root]=heap[child];
        child=root;
        root=(child-1)/2;
    }
    heap[child]=num;
    n++;

}

/*删除函数,对于最小堆和最大堆而言,删除是针对于根节点而言。
将二叉树的最后一个节点替换到根节点,然后自顶向下调整。*/
void DeleteHeap()
{
    heap[0]=heap[n-1];
    n--;
    AdjustHeap(0);
}

void BuildHeap()
{
    for(int i=(n-2)/2; i>=0; i--)
        AdjustHeap(i);
}
void Display()
{
    for(int i=0; i<n; i++)
        printf("%d%c", heap[i], i==n-1?\n: );
}

int main()
{
    while(~scanf("%d", &n))
    {
        for(int i=0; i<n; i++)
            scanf("%d", &heap[i]);
        BuildHeap();
        Display();

        int a;
        scanf("%d", &a);
        InsertHeap(a);
        Display();

        DeleteHeap();
        Display();
    }
    return 0;
}
/*
6
16 7 3 20 17 8
30
*/

 

堆的基本操作