蓝桥杯-横向打印二叉树(模拟)

横向打印二叉树:http://lx.lanqiao.org/problem.page?gpid=T34

问题描述

二叉树可以用于排序。其原理很简单:对于一个排序二叉树添加新节点时,先与根节点比较,若小则交给左子树继续处理,否则交给右子树。

当遇到空子树时,则把该节点放入那个位置。

比如,10 8 5 7 12 4 的输入顺序,应该建成二叉树如下图所示,其中.表示空白。

...|-12
10-|
...|-8-|
.......|...|-7
.......|-5-|
...........|-4

本题目要求:根据已知的数字,建立排序二叉树,并在标准输出中横向打印该二叉树。

输入格式

输入数据为一行空格分开的N个整数。 N<100,每个数字不超过10000。

输入数据中没有重复的数字。

输出格式

输出该排序二叉树的横向表示。为了便于评卷程序比对空格的数目,请把空格用句点代替:

样例输入1
10 5 20
样例输出1
...|-20
10-|
...|-5
样例输入2
5 10 20 8 4 7
样例输出2
.......|-20
..|-10-|
..|....|-8-|
..|........|-7
5-|
..|-4


这题好麻烦,目前还没想到可以不保存在数组中直接输出的方法

感觉题目的样例不能准确表明各种格式

大概:

465 32413 1231 45 17 674 14 5756

这组样例(不要在意范围)应该输出

....|-32413-|
....|.......|......|5756
....|.......|-1231-|
....|..............|-674
465-|
....|-45-|

.........|-17-|

..............|-14

就对了


#include <cstdio>
#include <algorithm>

using namespace std;

struct Node {
    int lson,rson,num,r;
    Node() {
        lson=rson=num=-1;
    }
}tr[105];
int a,cnt,l=1,sta;
char ans[105][605];

inline int getLen(int n) {//返回数字n的长度
    cnt=n<=0?1:0;
    while(n) {
        ++cnt;
        n/=10;
    }
    return cnt;
}

void add(int i,int lv) {//向排序二叉树添加一个数a
    if(tr[i].num>a) {
        if(tr[i].lson==-1) {
            tr[i].lson=l;
            tr[l++].num=a;
            return ;
        }
        add(tr[i].lson,lv+1);
    }
    else {
        if(tr[i].rson==-1) {
            tr[i].rson=l;
            tr[l++].num=a;
            return ;
        }
        add(tr[i].rson,lv+1);
    }
}

void print(int i,int lv,int num) {//将横向二叉树初步输出到ans数组中
    if(tr[i].rson!=-1)
        print(tr[i].rson,lv+1,num+getLen(tr[i].num)+(lv==1?1:3));

    int j=0;
    for(;j<num;++j)
        ans[sta][j]='.';
    sprintf(ans[sta]+j,"%s%d%s",lv==1?"\0":"|-",tr[i].num,((tr[i].lson==-1&&tr[i].rson==-1)?"\n\0":"-|\n\0"));
    tr[i].r=sta++;
    if(tr[i].lson!=-1)
        print(tr[i].lson,lv+1,num+getLen(tr[i].num)+(lv==1?1:3));
}

void format(int i,int lv,int num) {//将初步得到的ans数组进行格式化,即添加'|'
    if(tr[i].rson!=-1) {
        int nxt=num+getLen(tr[i].num)+(lv==1?1:3);
        format(tr[i].rson,lv+1,nxt);
        for(int j=tr[tr[i].rson].r;j<tr[i].r;++j)
            ans[j][nxt]='|';
    }
    if(tr[i].lson!=-1) {
        int nxt=num+getLen(tr[i].num)+(lv==1?1:3);
        format(tr[i].lson,lv+1,nxt);
        for(int j=tr[i].r+1;j<=tr[tr[i].lson].r;++j)
            ans[j][nxt]='|';
    }
}

int main() {
    scanf("%d",&a);
    tr[0].num=a;
    while(1==scanf("%d",&a))
        add(0,1);
    sta=0;
    print(0,1,0);
    format(0,1,0);
    for(int i=0;i<sta;++i)
        printf("%s",ans[i]);
    return 0;
}


你可能感兴趣的:(模拟,蓝桥杯)