蓝桥杯横向打印二叉树(中序+先序遍历)

挺繁琐的一道模拟题。。。

首先建一颗二叉树。

然后一次中序遍历求出所有节点所在的行。

然后再进行一次dfs画丨线就行了。

时间限制:1.0s   内存限制:256.0MB
 

   

 
问题描述

二叉树可以用于排序。其原理很简单:对于一个排序二叉树添加新节点时,先与根节点比较,若小则交给左子树继续处理,否则交给右子树。

当遇到空子树时,则把该节点放入那个位置。

比如,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
 
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <string>
#include <sstream>
using namespace std;
#define N 11000

int g[110];
int chg[10100];
char mat[110][1010];
char str[10010];
int n;
int l[N],r[N];
int line[N]; //用来记录,每个数字对应的行号
int head;
int lineid;

void b_insert(int num,int now)
{
	if(num<now)//到左子树
	{
		if(l[now]==-1)
		{
			l[now]=num;
		}
		else b_insert(num,l[now]);
	}
	else
	{
		if(r[now]==-1)
		{
			r[now]=num;
		}
		else b_insert(num,r[now]);
	}
}

void line_dfs(int cur)
{
	if(r[cur]!=-1) line_dfs(r[cur]);
	line[cur]=lineid++;
	if(l[cur]!=-1) line_dfs(l[cur]);
}

void dfs(int cur,int pos)
{
	int tcur=cur;
	for(int i=pos+chg[cur]-1;i>=pos;i--)
	{
		mat[ line[cur] ] [ i ]=tcur%10+'0';
		tcur/=10;
	}
	if(r[cur]!=-1||l[cur]!=-1)
	{
		mat[ line[cur] ][ pos+chg[cur] ]='-';
		if(r[cur]!=-1)
		{
			for(int i=line[r[cur]];i<=line[cur];i++)
				mat[i][pos+chg[cur]+1 ]='|';
			mat[ line[ r[cur] ] ] [ pos+chg[cur]+2 ]='-';
			dfs(r[cur],pos+chg[cur]+3);
		}

		if(l[cur]!=-1)
		{
			for(int i=line[cur];i<=line[ l[cur] ];i++)
				mat[i][pos+chg[cur]+1 ]='|';
			mat[ line[ l[cur] ] ] [ pos+chg[cur]+2 ]='-';
			dfs(l[cur],pos+chg[cur]+3);
		}
	}
	//只要把行位置确定了,其他的就好像比较好弄了
}

int main()
{
	//妹的,逼我用streamstring
	//freopen("w","C:\Users\Administrator\Desktop\out.txt",stdout);
	gets(str);
	stringstream in(str);
	n=0;
	while(in>>g[n]) n++;
	//获取到了所有数字,现在进入正题
	for(int i=0;i<=10000;i++)
	{
		if(i<10) chg[i]=1;
		else if(i<100) chg[i]=2;
		else if(i<1000) chg[i]=3;
		else if(i<10000) chg[i]=4;
		else chg[i]=5;
	}

	memset(l,-1,sizeof(l));
	memset(r,-1,sizeof(r));
	head=g[0];
	for(int i=1;i<n;i++)
	{
		//开始建树
		b_insert(g[i],head);
	}//才发现,建树是如此简单,但是不能排序的树又有什么吊用
	//用中序遍历可以确定每个数字的行
	lineid=0;
	line_dfs(head);
	dfs(head,0);
	for(int i=0;i<n;i++)
	{
		int j=1000;
		for(;j>=0;j--)
			if(mat[i][j]!=0) break;
		for(;j>=0;j--)
			if(mat[i][j]==0) mat[i][j]='.';
	}
	for(int i=0;i<n;i++)
	{
		printf("%s",mat[i]);
		printf("
");
	}
	return 0;
}
原文地址:https://www.cnblogs.com/chenhuan001/p/4362582.html