二叉树的字符图形显示程序

二叉树的字符图形显示程序

 

实验内容及要求:

设二叉树采用二叉链表存储结构,结点数据域为字符类型。编写控制台应用程序采用先序遍历法建立二叉树存储结构并实现二叉树的字符图形显示。输入及输出示例如下:

输入: ABDH##I##EJ##K##CFL##M##GN##O##¿     (#表示NULL指针域,¿表示回车键)

输出:

              A               行1

      ________|________       行2  横线由至少2个下划线字符组成,竖线是一个|字符

      |               |       行3

      B               C       行4

  ____|____       ____|____   行5

  |       |       |       |   行6

  D       E       F       G   行7

__|__   __|__   __|__   __|__ 行8  (行8的每根水平线由2个下划线字符组成)

|   |   |   |   |   |   |   | 行9

H   I   J   K   L   M   N   O 行10

输入: A#B#C##¿

输出:

      A

      |____

          |

          B

          |__

            |

            C

输入: AB#DE##F##CG###¿

输出:

              A

      ________|________

      |               |

      B               C

      |____       ____|   

          |       |       

          D       G       

        __|__               

        |   |               

        E   F               

输入: AB##C##¿

输出:

A

__|__

|   |

B   C                      

实验目的:对于二叉树(二叉链表)存储结构,综合运用所学知识,通过分析及算法设计解决课堂及教材未讲过的问题。

 

#include<iostream>
#include <conio.h>
#include<fstream>
#include<iomanip>
#include<Windows.h>
#include<math.h>
using namespace std;

int depth;//数的总层数
int countnode = 0;//节点计数器
typedef struct Tree
{
	char e;
	Tree* lchild;
	Tree* rchild;
	Tree* parent;
}T;//二叉树三叉链表

void goto_xy(int x, int y)
{
	HANDLE hOut;
	hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos = { x,y };
	SetConsoleCursorPosition(hOut, pos);
}//从网上找到的移动光标函数

void PrintfSpace()
{
	goto_xy(0, 20);
	for(int i =0;i<15;i++)
		for (int j = 0; j < 80; j++)
		{
			cout << " ";
		}
}//打印大量空格,防止二叉树图形和程序运行完后控制台显示的字重合

T* CreatTree(T* bt, char* temp)//先序建立二叉树
{
	static int i = 0;
	char c;

	if ((c = temp[i++]) == '#')//括号很重要,因为==的优先级大于赋值运算符
		return 0;
	else
	{
		bt = new T;
		countnode++;
		bt->e = c;
		bt->lchild = CreatTree(bt->lchild, temp);
		bt->rchild = CreatTree(bt->rchild, temp);
		return bt;
	}
}

void PreorderII(T* bt)
{
	if (!bt)return;
	else
	{
		cout << bt->e << " ";
		PreorderII(bt->lchild);
		PreorderII(bt->rchild);
	}
}//前序遍历

void PrintH(int n)
{
	for (int i = 0; i < n; i++)
	{
		cout << '_';
	}
}//打印指定数量的下划线

int CountDepth(T* bt)
{
	int hl, hr;
	if (!bt)
		return 0;
	hl = CountDepth(bt->lchild);
	hr = CountDepth(bt->rchild);
		return max(hl,hr)+1;
}//计算树的深度来确认横线的长短
void Display(T* bt, int k, int distance, int j)//根节点bt,层号k,横坐标distance,行号j,左右儿子标志flag
{
	if (!bt)return;
	goto_xy(distance, j);
	cout << bt->e;
	int offset = 2 << (depth - k);//左右儿子相对于根节点的偏移量
	j++;
	if (bt->lchild)
	{
		goto_xy(distance - offset, j);
		PrintH(offset);
		goto_xy(distance - offset, j + 1);
		cout << "|";
	}
	if (bt->rchild)
	{
		goto_xy(distance + 1, j);
		PrintH(offset);
		goto_xy(distance + offset, j + 1);
		cout << "|";
	}
	if (bt->lchild || bt->rchild)
	{
		goto_xy(distance, j);
		cout << "|";
	}
	//打印左右两边的下划线以及中间的竖线
	j++;//打印完进入下一行
	Display(bt->lchild, k+1, distance - offset, j + 1);
	Display(bt->rchild, k+1, distance + offset, j + 1);
	//递归打印左右子树
	return;
}

int main(void)
{
	char temp[1024] = { 0 };
	cin >> temp;
	T* bt = 0;
	bt = CreatTree(bt, temp);
	PreorderII(bt);
	depth = CountDepth(bt);
	Display(bt, 1, 60, 0);//起始横坐标为(60,0)
	PrintfSpace();
	return 0;
}

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值