藍橋杯_橫向打印二叉樹

題目大意

讀入一棵二叉搜索樹並橫向打印
樣例
10 8 5 7 12 4 

樣例輸出
...|-12
10-|
...|-8-|
.......|...|-7
.......|-5-|
...........|-4

思路

打印的 "|" 其實是子節點和祖先節點的連接,如果在搜索種能記錄節點自身一行最末尾的 "|", 使其子節點能夠打印與祖先節點的連接,就可以打印成樹,但子節點不是和所有祖先節點都有連接的,子節點和直接父親節點一定有連接。
在例子中,搜索過程:8->5->4     當搜索到5時,記錄中有節點8的末尾位置,然後放入5的末尾位置後搜索到4時,4卻不與8直接連接。如果節點i是其父親節點的左子樹,當從i往i的左子樹搜索時,應該取出記錄中的i的父節點記錄,回溯後放回父節點記錄,取出自身記錄。

i和i的子樹需要打印的位置的差別除了子樹需要打印i的位置以外,就只需要判斷子樹是否需要打印i的父親節點。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#define INF 0x3f3f3f3f
#define rep0(i, n) for (int i = 0; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define rep_0(i, n) for (int i = n - 1; i >= 0; i--)
#define rep_1(i, n) for (int i = n; i > 0; i--)
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define mem(x, y) memset(x, y, sizeof(x))
#define MAXN 110
using namespace std;
typedef pair<int, int> pp;
struct Node
{
    int v, dep;
    int l, r;
};
Node tr[MAXN];
int id = 0;
void ins(int t, int v)
{
    if (tr[t].v < v)
    {
        if (tr[t].r >= 0)
            ins(tr[t].r, v);
        else
        {
            tr[t].r = id;
            tr[id].v = v;
            tr[id].dep = tr[t].dep + 1;
            tr[id].l = tr[id].r = -1;
            id++;

        }
    }
    else if (tr[t].v > v)
    {
        if (tr[t].l >= 0)
            ins(tr[t].l, v);
        else
        {
            tr[t].l = id;
            tr[id].v = v;
            tr[id].dep = tr[t].dep + 1;
            tr[id].l = tr[id].r = -1;
            id++;
        }
    }
}

vector<pp> p;
void dfs(int u)
{
    int l = tr[u].l, r = tr[u].r;
    int cnt = 0;
    if (p.size() > 0)
        cnt = p.back().second;

    if (tr[u].dep > 0)
        cnt++;

    int tmp = tr[u].v;

    while (tmp)
    {
        cnt++;
        tmp /= 10;
    }
    if (l >= 0 || r >= 0)
        cnt += 2;

    pp bk, prs;
    int flag = 0, flag1 = 0;
    if (p.size() > 0)
    {
        bk = p.back();
        p.pop_back();

        flag = 1;
    }
    prs.first = tr[u].v;
    prs.second = cnt;

    if (flag && bk.first < tr[u].v)
    {
        flag1 = 1;
    }
    else if (flag)
    {
        p.push_back(bk);
    }

    p.push_back(prs);
    if (r >= 0)
        dfs(r);

    tmp = 0;

    for (int i = 0; i < p.size() - 1; i++)
    {


        while (tmp < p[i].second - 1)
        {
                printf(".");
                tmp++;
        }
        printf("|");
        tmp++;
    }


    if (flag1)
    {
        while (tmp < bk.second - 1)
        {
            printf(".");
            tmp++;
        }
        printf("|");
    }

    if (tr[u].dep > 0)
        printf("-");

    printf("%d", tr[u].v);
    if (l >= 0 || r >= 0)
        printf("-|");
    printf("\n");



    if (flag1)
    {
        p.pop_back();
        p.push_back(bk);
        p.push_back(prs);

    }
    else if (flag)
    {
        p.pop_back();
        p.pop_back();
        p.push_back(prs);
    }


    if (l >= 0)
        dfs(l);

    p.pop_back();
    if (p.size() > 0 && p.back().first != bk.first)
        p.push_back(bk);
    if (p.size() == 0)
        p.push_back(bk);


}
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif // ONLINE_JUDGE
    int tmp;
    scanf("%d", &tmp);
    tr[id].l= tr[id].r = -1;
    tr[id].dep = 0;
    tr[id++].v = tmp;
    while (scanf("%d", &tmp) != EOF)
    {
        ins(0, tmp);
    }

    dfs(0);


    return 0;
}

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