历届试题 横向打印二叉树
时间限制: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
题解:
这题就是模拟建树,然后后序遍历二叉树
难点就是怎样打印出那条树枝。我这里用了保存位置的方法。由题目可以得到右节点的左边会有树枝;左节点的右边会有树枝,然后模拟出来就行了
扫描二维码关注公众号,回复:
1624791 查看本文章
下面是代码,有点难懂
#include<stdio.h> #include<iostream> #include<algorithm> using namespace std; int lef[10010]; int rig[10010]; int root; int ne_line[10010][100]; //保存每个数字需要的划线 void built(int n, int r) { if(n > r) { if(rig[r] == 0) { rig[r] = n; return ; } else built(n,rig[r]); } else { if(lef[r] == 0) { lef[r] = n; return ; } else built(n,lef[r]); } } bool isye(int num) { //是否为最低子叶 if(lef[num] == 0 && rig[num]==0) return true; else return false; } int h_num(int num){ //计算该数字有多少位 int n = 0; while(num != 0){ num/=10;n++; } return n; } void cpy(int curroot, int lr){ //复制数组,lr为1,0为左右 if(lr){ if(lef[curroot]){ memcpy(ne_line[lef[curroot]],ne_line[curroot],sizeof(ne_line[curroot])); cpy(lef[curroot],lr); } } else{ if(rig[curroot]){ memcpy(ne_line[rig[curroot]],ne_line[curroot],sizeof(ne_line[curroot])); cpy(rig[curroot],lr); } } } void pit(int curroot,int num) { //num为点数 if(isye(curroot)) { for(int i = 1; i <= num; i++) { if(ne_line[curroot][i]) printf("|"); else printf("."); } printf("-%d\n",curroot); }else if(curroot == root){ int anum = 2+h_num(curroot); ne_line[rig[curroot]][anum] = 1; ne_line[lef[curroot]][anum] = 1; cpy(rig[curroot],1); cpy(lef[curroot],0); if(rig[curroot]) pit(rig[curroot],num+anum); printf("%d-|\n",curroot); if(lef[curroot]) pit(lef[curroot],num+anum); }else { int anum = num+3+h_num(curroot); ne_line[rig[curroot]][anum] = 1; ne_line[lef[curroot]][anum] = 1; cpy(rig[curroot],1); cpy(lef[curroot],0); if(rig[curroot]) pit(rig[curroot],anum); for(int i = 1; i <= num; i++) { if(ne_line[curroot][i]) printf("|"); else printf("."); } printf("-%d-|\n",curroot); if(lef[curroot]) pit(lef[curroot],anum); } } int main() { //freopen("in.txt","r",stdin); scanf("%d",&root); int tmp; while(scanf("%d",&tmp) == 1) { built(tmp,root); } pit(root,0); return 0; }