關於二叉樹

HDU - 1710

題意:前序中序求後序

#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;
const int maxn = 1050;
int a[maxn],b[maxn];
int n;
struct node
{
    int v,l,r;
}tr[maxn << 2];
int num = 0;
int build(int prel,int prer,int inl,int inr)
{

    if(prer - prel < 0) return -1;
    int id = num++;
    tr[id].v = a[prel];
    int mid= -1;
    for(int i = inl; i <= inr; i++)
        if(b[i] == a[prel]){mid = i;break;}
    int lnum = mid - inl, rnum = inr-mid;
    if(lnum >= 1)tr[id].l = build(prel+1,prel+lnum,inl,mid-1);
    if(rnum >= 1)tr[id].r = build(prel+1+lnum,prer,mid+1,inr);
    return id;
}
int flag = 0;
void order(int i)
{
    if(tr[i].l != -1)order(tr[i].l);
    if(tr[i].r != -1)order(tr[i].r);
    if(flag == 0)
    {
        printf("%d",tr[i].v);
        flag = 1;
    }
    else printf(" %d",tr[i].v);
}
int main()
{
    while(~scanf("%d",&n))
    {
        num = 0;    flag = 0;
        for(int i = 0; i < n; i++)  tr[i].l = tr[i].r = -1;
        for(int i = 1; i <= n ; i++)    scanf("%d",&a[i]);
        for(int j = 1; j <= n ; j++)    scanf("%d",&b[j]);
        build(1,n,1,n);
        order(0);
        printf("\n");
    }
    return 0;
}


HDU 1622

題意:輸入噁心,然後層次輸出二叉樹

#include <cstdio>
#include <cstring>
#include <iostream>
#include <sstream>
#include <queue>
using namespace std;
const int maxn = 1024;
const int maxm = 1e4;
struct node
{
    int v,l,r;
}tr[maxn];
char s[maxm];
int out[maxn];

void print(int mark)
{
    if(mark == 1) {printf("not complete\n"); return;}
    queue<node> Q;
    Q.push(tr[1]);
    int thnum = 0;
    while(!Q.empty())
    {
        node temp = Q.front(); Q.pop();
        int v  = temp.v;
        out[thnum++] = v;
        if(temp.l) Q.push(tr[temp.l]);
        if(temp.r) Q.push(tr[temp.r]);
    }
    for(int i = 0; i < thnum; i++)
        if(!out[i]){mark = 1;break;}
    if(mark == 1) {printf("not complete\n"); return;}
    for(int i = 0; i < thnum; i++)
        i == 0 ? printf("%d",out[i]) : printf(" %d",out[i]);
    printf("\n");
}
char temp[20];
int flag = 0,mark = 0,num = 1;
void init()
{
    num = 1; print(mark); mark = 0;flag = 0;
    memset(tr,0,sizeof(tr));
}
int main()
{
    while(cin.getline(s,maxm))
    {
        stringstream ss;
        ss << s;
        while(ss >> temp)
        {
            if(strcmp(temp,"()") == 0) {flag = 1; init();continue;}
            int tlen = strlen(temp),thv = 0,stj = -1;
            for(int i = 1; i < tlen; i++)
            {
                if(temp[i] == ','){stj = i; break;}
                thv = thv*10 + temp[i] - '0';
            }
            int th = 1;
            for(int i = stj+1; i < tlen-1; i++)
            {
                int thop = temp[i] == 'L' ? 0 : 1;
                if(thop == 0)
                {
                    if(tr[th].l == 0) tr[th].l = ++num;
                    th = tr[th].l;
                }
                else
                {
                    if(tr[th].r == 0) tr[th].r = ++num;
                    th = tr[th].r;
                }
            }
            if(stj + 1 == tlen-1)
            {
                if(tr[1].v == 0)tr[1].v = thv;
                else mark = 1;
            }
            else
            {
                if(tr[th].v != 0) mark = 1;
                else tr[th].v = thv;
            }
        }
    }
    return 0;
}


POJ - 1095

題意:讓你求第n個二叉樹的中序遍歷,注意這個順序是優先右邊,然後左邊。

這個時候我們可以推出一個很神奇的公式:由n個結點組成的不同二叉樹種類有:h(n) = h(0)*h(n-1) + h(1) * h(n-2) + …+h(n-1)*h(0);

好吧其實我已經知道了卡特蘭數..

都知道卡特蘭數是一個特別大的玩意,所以我們先打個表,發現5 0000 0000 的時候最多18個點。

這樣由這個卡特蘭數我們就可以推出左子樹的數量,右子樹的數量,這樣一直遞推到底,就建了一棵樹出來。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 30;
int n;
int h[20];
int sum[20],lson[maxn],rson[maxn],lid[maxn],rid[maxn];

void pre()
{
    h[0] = 1;   sum[0] = 1;
    h[1] = 1;   sum[1] = 2;
    h[2] = 2;   sum[2] = 4;
    for(int i = 2; i <= 18; i++)
    {
        int ans = 0;
        for(int j = 0; j < i ; j++)
            ans += h[j]*h[i-j-1];
        h[i] = ans;
        sum[i] = sum[i-1] + ans;
    }
}
int tot = 1;
void getit(int sum,int num,int id)
{
    int temp = 0;
    for(int i = 0; i < num; i++)
    {
        temp += h[i]*h[num-1-i];
        if(temp > sum)
        {
            temp -= h[i]*h[num-1-i];
            lson[id] = i;
            rson[id] = num-1-i;
            break;
        }
    }
    temp = sum - temp;
    int ls = temp / h[rson[id]], rs = temp % h[rson[id]];
    if(lson[id] > 0) {int l = ++tot; lid[id] = l; getit(ls,lson[id],l);}
    if(rson[id] > 0) {int r = ++tot; rid[id] = r; getit(rs,rson[id],r);}
}
void print(int i)
{
    if(lson[i]!=0)
    {   printf("(");    print(lid[i]);    printf(")");    }
    printf("X");
    if(rson[i])
    {   printf("(");    print(rid[i]);  printf(")");    }
}
int main()
{
    pre();
    while(~scanf("%d",&n) && n)
    {
        for(int i = 0; i < 30; i++)
            rson[i] = lson[i] = rid[i] = lid[i] = 0;
        tot = 1;
        int num = 0;
        for(int i = 0; i < 19; i++)
            if(sum[i] > n) {num = i; break;}
        getit(n-sum[num-1],num,1);
        print(1);
        printf("\n");
    }
    return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章