实现堆结构

来源:互联网 发布:win10以太网未识别网络 编辑:程序博客网 时间:2024/05/18 13:47

题目如下:

描述

定义一个数组,初始化为空。在数组上执行两种操作:

1、增添1个元素,把1个新的元素放入数组。

2、输出并删除数组中最小的数。

使用堆结构实现上述功能的高效算法。

输入
第一行输入一个整数t,代表测试数据的组数。
对于每组测试数据,第一行输入一个整数n,代表操作的次数。
每次操作首先输入一个整数type。
当type=1,增添操作,接着输入一个整数u,代表要插入的元素。
当type=2,输出删除操作,输出并删除数组中最小的元素。
1<=n<=100000。
输出
每次删除操作输出被删除的数字。
样例输入
251 11 21 32241 51 11 72
样例输出
121
提示
每组测试数据的复杂度为O(nlgn)的算法才能通过本次,否则会返回TLE(超时)

需要使用最小堆结构来实现本题的算法



以前写树的代码时一直用的链表形式,现在试了一下数组的写法,感觉比较也比较好理解,写法也比较简单。代码及注释如下:

#include<iostream>#include<cstdio>#include<cstring>using namespace std;int a[100010];int n;//下标下移,在删除后更新树时需要用到void down( int root ){    int son =  2*root;  //记录根节点的左儿子    int t = a[root];       while( son <= n)    {        if( son <= n -1  && a[son] > a[son+1]) //防止数组越界,且记录较小值儿子节点的下标            son++;        if( t > a[son])   //更新节点。        {            a[root] = a[son];            root = son;            son = 2*root;        }        else break;    }    a[root] = t;}//数组下标上移,插入节点时用到。void up( int son ){    int t = a[son];    int tson = son;    while( (tson > 1)&&( a[tson/2] > t))  //更新节点。    {        a[tson] = a[tson/2];        tson = tson/2;    }    a[tson] = t;}void charu( int  t){    a[ ++n ] = t;    up( n );}void del( ){    if(n==0)        return ;    cout << a[1] << endl; //根节点肯定是最小值。    a[1] = a[n--];    down( 1 );}int main(){    int t;    scanf("%d",&t);    while( t-- )    {        n = 0;        int type;        int m;        scanf("%d",&m);        for(int i = 0; i< m; i++)        {            scanf("%d",&type);            if(type == 1)            {                int b;                scanf("%d",&b);                charu( b ) ;            }            else            {                del();            }        }    }    return 0;}


0 0
原创粉丝点击