历届试题 横向打印二叉树
时间限制: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<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;
}