Codeforces Round #353 (Div. 2) D. Tree Construction (BST询问父亲节点)

原题请戳这里

题意:

给出n个不同的数,按照给出的顺序构造二叉排序树BST,第1个数为根节点。输出2-n个

节点的父亲节点。

 

分析:

二叉排序树的平均复杂度是log2n,最坏情况下变成线性的,复杂度为n。

对n个节点的插入操作如果用结构体指针的写法最坏情况下为n2=1010,这样会超时。

开始没有注意这点,TLE。但是正好复习了BST的插入操作递归和非递归的写法。

 

易知,插入的数的父亲节点是已插入的比它大或者比它小的与其最接近的数之一。

这个题利用set保存输入的数,用两个map分别记录左右孩子。

每次找到第一个大于v的数的位置。如果是最后一个,则前一个比它小的数的右孩子是该数;

否则,若找到的位置的左孩子为空,则该数为其左孩子,若不为空,则该数为前一个位置比

它小的数的右孩子。

这样复杂度是nlogn(循环n,lower_bound二分原理复杂度为logn)

 

#include<cstdio>
#include<map>
#include<algorithm>
#include<iostream>
#include<set>

using namespace std;

typedef long long ll;

set<int> numbers;
map<int,int> L,R;

int main()
{
    int n,v;
    while(~scanf("%d",&n))
    {
        numbers.clear();
        L.clear();
        R.clear();
        for(int i=0;i<n;i++)
        {
            scanf("%d",&v);
            if(i==0) numbers.insert(v);
            else
            {
                set<int>::iterator iter;
                iter = numbers.lower_bound(v);
                if(iter == numbers.end()) R[*(--iter)] = v;
                else
                {
                    if(!L[*iter]) L[*iter] = v;
                    else R[*(--iter)] = v;
                }
                if(i==1) printf("%d",*iter);
                else printf(" %d",*iter);
                numbers.insert(v);
            }
        }
        printf("\n");
    }
    return 0;
}

 

超时的BST插入非递归写法

#include<cstdio>
#include<map>
#include<algorithm>
#include<iostream>

using namespace std;

typedef long long ll;

struct node
{
    int val;
    struct node *lchild,*rchild,*fa;
};
int x[100005];
struct node *rt;
map<int,int> mp;

void insert_(int x,struct node*cur)
{
    struct node* ch = (struct node*)malloc(sizeof(struct node));
    ch->val = x;
    ch->lchild = ch->rchild = NULL;
    struct node* parent;
    while(cur!=NULL)
    {
        parent = cur;
        if(x > parent->val) cur = parent->rchild;
        else cur = parent->lchild;
    }
    ch->fa = parent;
    mp[x] = parent->val;
    if(parent->val < x)
        parent->rchild = ch;
    else
        parent->lchild = ch;
}

int main()
{
    int n,root;
    while(~scanf("%d",&n))
    {
        mp.clear();
        rt = (struct node*)malloc(sizeof(struct node));
        scanf("%d",&root);
        rt->val = root;
        rt->lchild = rt->rchild = NULL;
        for(int i=1;i<n;i++)
        {
            scanf("%d",&x[i]);
            insert_(x[i],rt);
        }
        for(int i=1;i<n-1;i++)
            printf("%d ",mp[x[i]]);
        printf("%d\n",mp[x[n-1]]);
    }
    return 0;
}

 

posted @ 2016-05-28 19:12  fukan  阅读(193)  评论(0编辑  收藏  举报