横向打印二叉树:http://lx.lanqiao.org/problem.page?gpid=T34
二叉树可以用于排序。其原理很简单:对于一个排序二叉树添加新节点时,先与根节点比较,若小则交给左子树继续处理,否则交给右子树。
当遇到空子树时,则把该节点放入那个位置。
比如,10 8 5 7 12 4 的输入顺序,应该建成二叉树如下图所示,其中.表示空白。
本题目要求:根据已知的数字,建立排序二叉树,并在标准输出中横向打印该二叉树。
输入数据为一行空格分开的N个整数。 N<100,每个数字不超过10000。
输入数据中没有重复的数字。
输出该排序二叉树的横向表示。为了便于评卷程序比对空格的数目,请把空格用句点代替:
这题好麻烦,目前还没想到可以不保存在数组中直接输出的方法
感觉题目的样例不能准确表明各种格式
大概:
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; }