挺繁琐的一道模拟题。。。
首先建一颗二叉树。
然后一次中序遍历求出所有节点所在的行。
然后再进行一次dfs画丨线就行了。
时间限制:1.0s 内存限制:256.0MB
问题描述
二叉树可以用于排序。其原理很简单:对于一个排序二叉树添加新节点时,先与根节点比较,若小则交给左子树继续处理,否则交给右子树。
当遇到空子树时,则把该节点放入那个位置。
比如,10 8 5 7 12 4 的输入顺序,应该建成二叉树如下图所示,其中.表示空白。
...|-12
10-|
...|-8-|
.......|...|-7
.......|-5-|
...........|-4
10-|
...|-8-|
.......|...|-7
.......|-5-|
...........|-4
本题目要求:根据已知的数字,建立排序二叉树,并在标准输出中横向打印该二叉树。
输入格式
输入数据为一行空格分开的N个整数。 N<100,每个数字不超过10000。
输入数据中没有重复的数字。
输出格式
输出该排序二叉树的横向表示。为了便于评卷程序比对空格的数目,请把空格用句点代替:
样例输入1
10 5 20
样例输出1
...|-20
10-|
...|-5
10-|
...|-5
样例输入2
5 10 20 8 4 7
样例输出2
.......|-20
..|-10-|
..|....|-8-|
..|........|-7
5-|
..|-4
..|-10-|
..|....|-8-|
..|........|-7
5-|
..|-4
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <string> #include <sstream> using namespace std; #define N 11000 int g[110]; int chg[10100]; char mat[110][1010]; char str[10010]; int n; int l[N],r[N]; int line[N]; //用来记录,每个数字对应的行号 int head; int lineid; void b_insert(int num,int now) { if(num<now)//到左子树 { if(l[now]==-1) { l[now]=num; } else b_insert(num,l[now]); } else { if(r[now]==-1) { r[now]=num; } else b_insert(num,r[now]); } } void line_dfs(int cur) { if(r[cur]!=-1) line_dfs(r[cur]); line[cur]=lineid++; if(l[cur]!=-1) line_dfs(l[cur]); } void dfs(int cur,int pos) { int tcur=cur; for(int i=pos+chg[cur]-1;i>=pos;i--) { mat[ line[cur] ] [ i ]=tcur%10+'0'; tcur/=10; } if(r[cur]!=-1||l[cur]!=-1) { mat[ line[cur] ][ pos+chg[cur] ]='-'; if(r[cur]!=-1) { for(int i=line[r[cur]];i<=line[cur];i++) mat[i][pos+chg[cur]+1 ]='|'; mat[ line[ r[cur] ] ] [ pos+chg[cur]+2 ]='-'; dfs(r[cur],pos+chg[cur]+3); } if(l[cur]!=-1) { for(int i=line[cur];i<=line[ l[cur] ];i++) mat[i][pos+chg[cur]+1 ]='|'; mat[ line[ l[cur] ] ] [ pos+chg[cur]+2 ]='-'; dfs(l[cur],pos+chg[cur]+3); } } //只要把行位置确定了,其他的就好像比较好弄了 } int main() { //妹的,逼我用streamstring //freopen("w","C:\Users\Administrator\Desktop\out.txt",stdout); gets(str); stringstream in(str); n=0; while(in>>g[n]) n++; //获取到了所有数字,现在进入正题 for(int i=0;i<=10000;i++) { if(i<10) chg[i]=1; else if(i<100) chg[i]=2; else if(i<1000) chg[i]=3; else if(i<10000) chg[i]=4; else chg[i]=5; } memset(l,-1,sizeof(l)); memset(r,-1,sizeof(r)); head=g[0]; for(int i=1;i<n;i++) { //开始建树 b_insert(g[i],head); }//才发现,建树是如此简单,但是不能排序的树又有什么吊用 //用中序遍历可以确定每个数字的行 lineid=0; line_dfs(head); dfs(head,0); for(int i=0;i<n;i++) { int j=1000; for(;j>=0;j--) if(mat[i][j]!=0) break; for(;j>=0;j--) if(mat[i][j]==0) mat[i][j]='.'; } for(int i=0;i<n;i++) { printf("%s",mat[i]); printf(" "); } return 0; }