《横向打印二叉树》

描述

二叉树可以用于排序。其原理很简单:对于一个排序二叉树添加新节点时,先与根节点比较,若小则交给左子树继续处理,否则交给右子树。
当遇到空子树时,则把该节点放入那个位置。
比如,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 

提示

【数据规模与约定】
对于100%的数据,满足N<100,每个数字不超过10000。

#include<iostream>
#include<sstream>
const int maxn = 200;
struct node{
	int left,right; 
	int left_s,right_s;
	int v,id,ak;
	char a[10];
}Nodes[maxn];

char map[maxn][maxn]; 

using namespace std;

void BinaryTree_set(int rt,int k){ 
	if(Nodes[k].v > Nodes[rt].v){
		Nodes[rt].right_s++; 
		if(Nodes[rt].right != -1){ 
			BinaryTree_set(Nodes[rt].right,k); 
		}else{ //右子树不存在 
			Nodes[rt].right = k;
		}
	}else{//同理 
		Nodes[rt].left_s++;
		if(Nodes[rt].left != -1){
			BinaryTree_set(Nodes[rt].left,k); 
		}else{
			Nodes[rt].left = k;
		}
	}
}

void Set_id(int rid,int k){  
	Nodes[k].id = rid + Nodes[k].right_s + 1; 
	if(Nodes[k].right != -1){
		Set_id(rid,Nodes[k].right);
	}
	if(Nodes[k].left != -1){
		Set_id(Nodes[k].id,Nodes[k].left); 
	}
}

void Map_set(int k,int index){
								
	for(int i = 0;i < Nodes[k].ak;i++){
		map[Nodes[k].id][index + i] = Nodes[k].a[Nodes[k].ak - i - 1];
	}
	index += Nodes[k].ak; 
	if(Nodes[k].right != -1 || Nodes[k].left != -1){
		map[Nodes[k].id][index++] = '-'; 
		
		int max = Nodes[k].id; 
		int min = Nodes[k].id; 
		
		if(Nodes[k].right != -1){ 
			min = Nodes[Nodes[k].right].id; 
			map[Nodes[Nodes[k].right].id][index + 1] = '-'; 
			Map_set(Nodes[k].right,index + 2); 
            index+2 ;
		}
		if(Nodes[k].left != -1){
			max = Nodes[Nodes[k].left].id;
			map[Nodes[Nodes[k].left].id][index + 1] = '-';
			Map_set(Nodes[k].left,index + 2); 
		}
		
		for(int i = min; i <= max;i++){ 
			map[i][index] = '|';
		}
		
		map[Nodes[k].id][index + 1] = '\0'; 
	}else{
		map[Nodes[k].id][index] = '\0';
		return;
	}
} 
 
int main(){
	string s;
	getline(cin,s);
	istringstream ss(s);
	int e;
	int n = 0;
	int A[maxn];
	while(ss >> e){
		A[n++] = e;
	}
	
	for(int i = 0;i < n;i++){
		int e = A[i];
		Nodes[i].right = Nodes[i].left = -1;
		Nodes[i].right_s = Nodes[i].left_s = 0;
		Nodes[i].v = e;
		Nodes[i].ak = 0;
		while(e){ 
			Nodes[i].a[Nodes[i].ak++] = e % 10 + '0';
			e = e / 10;
		}
	}
	for(int i = 1;i < n;i++){
		BinaryTree_set(0,i);
	}
	Set_id(0,0);
	for(int i = 1;i < maxn;i++){
		for(int j = 0;j < maxn;j++){
			map[i][j] = '.';	
		}
	}
	Map_set(0,0);
	for(int i = 1;i <=n;i++){
		cout<<map[i]<<endl; 
	} 
	return 0;
} 

  • 12
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值