问题描述
二叉树可以用于排序。其原理很简单:对于一个排序二叉树添加新节点时,先与根节点比较,若小则交给左子树继续处理,否则交给右子树。
当遇到空子树时,则把该节点放入那个位置。
比如,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<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#define bug(x) printf("%d****\n",x)
using namespace std;
typedef long long ll;
map<int,int> pos;
struct node{
int val,fa;
node* l,*r;
node(int _fa=-1,int _val=-1){
fa=_fa,val=_val,l=r=NULL;
}
};
const int maxn=410;
char mp[maxn][maxn];
int arr[maxn];
queue<node*> q1,q2;
void insert_tr(node*& tr,int val,int fa){
if(tr==NULL){
tr=new node(fa,val);
return;
}
if(val>tr->val)
insert_tr(tr->l,val,tr->val);
else
insert_tr(tr->r,val,tr->val);
}
int cnt;
int num[10];
void print(){
for(int i=0;i<=3;i++){
for(int j=0;j<=5;j++){
printf("%c",mp[i][j]);
}
printf("\n");
}
}
void put_char(int val,int& p){
int cnt=0,tmp=val;//卧槽,你别把数给改了啊
while(tmp){
num[cnt++]=tmp%10;
tmp/=10;
}
for(int i=cnt-1,j=0;i>=0;i--,j++){
mp[pos[val]][p+j]=num[i]+'0';
}
p+=(cnt-1);
}
int put_val(int pf,int val,int dep,int rt){
int p=maxn-1;
while(mp[pf][p]!='|')
p--;
if(pos[val]<pf){
for(int i=pos[val];i<=pf;i++){
mp[i][p]='|';
for(int j=0;j<p;j++){
if(mp[i][j]==0)mp[i][j]='.';
}
}
}
else{
for(int i=pf+1;i<=pos[val];i++){
mp[i][p]='|';
for(int j=0;j<p;j++){
if(mp[i][j]==0)mp[i][j]='.';
}
}
}
p++;
if(val!=rt){
mp[pos[val]][p]='-';
p++;
}
put_char(val,p);
return p;
}
int check(char ch){
if(ch>='0'&&ch<='9') return 1;
return 0;
}
void put_xian(int val){
int p=maxn-1;
while(!check(mp[pos[val]][p]))
p--;
p++;
mp[pos[val]][p]='-';
p++;
mp[pos[val]][p]='|';
}
/*
头一次写这样的模拟题,尽管写的时间比较长,写了有2个小时,但是一发过,还是蛮爽的
还是汝佳大神的建议中肯,先写简单的,把他们抽象成函数,这样的话,就会比较好写,
不会写的很乱
*/
int main(){
for(int i=0;i<maxn;i++){
for(int j=0;j<maxn;j++)
mp[i][j]=0;
}
cnt=1;
int val,pre=-1;
node* tr=new node(val);
while(scanf("%d",&val)==1){
if(cnt==1){
tr->val=val;
tr->fa=val;
}
else
insert_tr(tr,val,pre);
pre=val;
arr[cnt++]=val;
}
sort(arr+1,arr+cnt);
for(int i=1;i<cnt;i++){
pos[arr[i]]=i;
}
mp[pos[tr->val]][0]='|';
q1.push(tr);
int dep=1,max_dep=1;
while(!q1.empty()||!q2.empty()){
if(dep&1){
while(!q1.empty()){
node* now=q1.front();
q1.pop();
int val=now->val;
int tmp=put_val(pos[now->fa],val,dep,tr->val);
if(now->l) q2.push(now->l);
if(now->r) q2.push(now->r);
if(now->l||now->r) put_xian(val);
max_dep=max(max_dep,tmp);
}
}
else{
while(!q2.empty()){
node* now=q2.front();
q2.pop();
int val=now->val;
int tmp=put_val(pos[now->fa],val,dep,tr->val);
if(now->l) q1.push(now->l);
if(now->r) q1.push(now->r);
if(now->l||now->r) put_xian(val);
max_dep=max(max_dep,tmp);
}
}
dep++;
}
for(int i=cnt-1;i>=1;i--){
for(int j=1;j<=max_dep;j++)
printf("%c",mp[i][j]);
printf("\n");
}
return 0;
}