二叉树的图形直观显示的初步实现

本文介绍了一种二叉树图形直观显示的初步实现方法,通过重新定义节点结构,利用队列按层遍历二叉树,并通过算法控制节点的输出位置和间隔,实现了对称显示。详细讨论了计算节点输出宽度和间隔的规律,以及如何处理实际存在的节点间隔。目前尚未添加节点之间的连接符号,但已经实现了基本的图形化输出。
摘要由CSDN通过智能技术生成

学习到了二叉树,认识到二叉树太有作用了。但每一次创建了二叉树,总想直观看一下二叉树的结序,以方便程序的调试。但二叉树的结构怎样才能直观显示出来呢?看了网上的一些资料和做法,要么看不懂,要么不满意。于是试着自己写代码,看能否达到目的。功夫不负有心人,经过不懈努力,终于弄出一个初步的结果。兴奋!!!本想进一步完善,添上一些符号把节点连起来再发出来,实在高兴忍不住了……哈哈!!!先上结果的图片:

下面简单说一下思路,欢迎大家指正并提出更好的办法。

基本思路:二叉树两条分支,从形状上来讲,左右是对称的。虽然不一定每个节点都有左右两个子节点,但是要直观显示时,位置分布上也要把空节点留出相应的空间来。这样,它始终是对称的。因此:我的方法就是“对称输出”,每个节点,包括空的节点,留出相应位置空间。

基本方法:思路虽然有了,但实现起来很困难。首先每个节点的信息有限,如果只有data,LChild,RChild等信息,就无法了解节点与其它同层节点以及父节点之间的信息与关系,输出时就无法控制了。

所以我的第一步:重新定义一个“节点”的结构,使它包括:父节点指针、深度(层次)、位置序号等成员数据,以上所说的难点就从定义上解决了。下面是节点的结构定义:

template<typename T>
struct BiTNode {
	BiTNode<T> *Lchild = NULL, *Rchild = NULL, *parent = NULL;
	T data;
	int depth = 0;
	int order = 0;
};

节点定义了,怎么在程序中实际生成这些数据呢?因为二叉树要直观图形输出,必须要按层的顺序了解足够的信息。所以首先要能够按层遍历二叉树的方法。这个不难,我还是用利用队列(Queue)的办法解决它。下面是我根据已存在的二叉树,按照自己定义的节点结构重新创建(即复制二叉树)的二叉树的方法代码:

//复制二叉树,按BiTNode结构类,添加深度、序号以及父节点等信息
template<typename T>
BiTNode<T> *CreateBiTTreeFrom(BiTNode<T> *p) {
	//复制p为根结点的树,并添加BiTNode相关变量信息。
	Queue<BiTNode<T> *> qbit;
	BiTNode<T> *root=NULL,*bitNode, *childNode;
	if (p) {
		//根结点复制
		root = new BiTNode<T>;
		root->data = p->data;
		root->depth = 1;
		//ordero为节点序号。节点序号编排原则:从0开始;空节点也要占据相应位置。非实际节点序号。
		root->order = 0;
		root->Lchild = p->Lchild;
		root->Rchild = p->Rchild;

		qbit.QInsert(root);
		//其它节点的复制循环,利用队列先进先出特点,按层序复制所有节点。
		while (!qbit.QEmpty()) {
			bitNode = qbit.QDelete();
			//根据父结点,创建左子节点并添加相关信息。
			if (bitNode->Lchild) {
				childNode = new BiTNode<T>;
				childNode->data = bitNode->Lchild->data;
				childNode->depth = bitNode->depth + 1;
				childNode->parent = bitNode;
				//根据父节点的序号确定上一层元素的个数,从而可以确定当前节点在当前层的序号。
				//序号计算要包括父结点中不存在的左或右子节点的数量。序号不是指实际存在的同层节点的序号。
				childNode->order = childNode->parent->order * 2;
				childNode->Lchild = bitNode->Lchild->Lchild;

				childNode->Rchild = bitNode->Lchild->Rchild;

				bitNode->Lchild = childNode;
				qbit.QInsert(bitNode->Lchild);
			}
			//根据父结点,创建右子节点并添加相关信息。
			if (bitNode->Rchild) {

				childNode = new BiTNode<T>;
				childNode->data = bitNode->Rchild->data;
				childNode->depth = bitNode->depth + 1;
				childNode->parent = bitNode;
				childNode->order = childNode->parent->order * 2 + 1;

				childNode->Lchild = bitNode->Rchild->Lchild;

				childNode->Rchild = bitNode->Rchild->Rchild;

				bitNode->Rchi
  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用EasyX图形实现二叉树图形遍历的示例代码。其中包括了前序遍历、中序遍历和后序遍历的图形化展示。 ```c++ #include <graphics.h> #include <conio.h> #include <stdio.h> #include <stdlib.h> //结构体 typedef struct tree { int data; struct tree *left; struct tree *right; }Tree; //创建二叉树 Tree *createTree() { Tree *p; int data; scanf("%d",&data); if(data == -1) p = NULL; else { p = (Tree*)malloc(sizeof(Tree)); p->data = data; p->left = createTree(); p->right = createTree(); } return p; } //前序遍历并图形化展示 void preOrder(Tree *p, int x, int y, int coe) { if(p) { char str[10]; settextcolor(RED); sprintf(str, "%d", p->data); outtextxy(x, y, str); //输出当前节点的值 if(p->left) { settextcolor(YELLOW); sprintf(str, "%d", p->left->data); line(x, y, x-coe, y+coe); //绘制连线 outtextxy(x-coe-20, y+coe-20, str); //输出左子节点的值 } preOrder(p->left, x-coe, y+coe, coe/2); //递归遍历左子 if(p->right) { settextcolor(YELLOW); sprintf(str, "%d", p->right->data); line(x, y, x+coe, y+coe); //绘制连线 outtextxy(x+coe+20, y+coe-20, str); //输出右子节点的值 } preOrder(p->right, x+coe, y+coe, coe/2); //递归遍历右子 } } //中序遍历并图形化展示 void inOrder(Tree *p, int x, int y, int coe) { if(p) { inOrder(p->left, x-coe, y+coe, coe/2); //递归遍历左子 char str[10]; settextcolor(RED); sprintf(str, "%d", p->data); outtextxy(x, y, str); //输出当前节点的值 if(p->left) { settextcolor(YELLOW); sprintf(str, "%d", p->left->data); line(x, y, x-coe, y+coe); //绘制连线 outtextxy(x-coe-20, y+coe-20, str); //输出左子节点的值 } if(p->right) { settextcolor(YELLOW); sprintf(str, "%d", p->right->data); line(x, y, x+coe, y+coe); //绘制连线 outtextxy(x+coe+20, y+coe-20, str); //输出右子节点的值 } inOrder(p->right, x+coe, y+coe, coe/2); //递归遍历右子 } } //后序遍历并图形化展示 void postOrder(Tree *p, int x, int y, int coe) { if(p) { postOrder(p->left, x-coe, y+coe, coe/2); //递归遍历左子 postOrder(p->right, x+coe, y+coe, coe/2); //递归遍历右子 char str[10]; settextcolor(RED); sprintf(str, "%d", p->data); outtextxy(x, y, str); //输出当前节点的值 if(p->left) { settextcolor(YELLOW); sprintf(str, "%d", p->left->data); line(x, y, x-coe, y+coe); //绘制连线 outtextxy(x-coe-20, y+coe-20, str); //输出左子节点的值 } if(p->right) { settextcolor(YELLOW); sprintf(str, "%d", p->right->data); line(x, y, x+coe, y+coe); //绘制连线 outtextxy(x+coe+20, y+coe-20, str); //输出右子节点的值 } } } int main() { initgraph(800, 600); //初始化图形窗口 setbkcolor(WHITE); settextstyle(20, 0, "宋体"); setlinestyle(PS_SOLID, 2); outtextxy(350, 50, "二叉树遍历图形演示"); outtextxy(100, 150, "请输入二叉树节点的值(-1表示空节点):"); Tree *root = createTree(); //创建二叉树 //前序遍历并图形化展示 outtextxy(50, 300, "前序遍历:"); preOrder(root, 400, 300, 200); //中序遍历并图形化展示 outtextxy(50, 400, "中序遍历:"); inOrder(root, 400, 400, 200); //后序遍历并图形化展示 outtextxy(50, 500, "后序遍历:"); postOrder(root, 400, 500, 200); getch(); closegraph(); //关闭图形窗口 return 0; } ``` 在运行程序后,用户可以输入二叉树的节点值,程序将会自动创建并展示二叉树的三种遍历方式的图形化展示。用户可以通过观察图形化展示,更直观地理解二叉树的遍历方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值