数据结构 &二叉树(三)

本文详细探讨了二叉树的创建过程,包括从键盘输入字符和通过字符串创建两种方式。通过实例展示了不同创建方法导致的不同二叉树结构,并解释了递归调用中使用字符串指针作为参数的重要性,确保正确遍历字符串并构建相同的二叉树。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇文章中我们主要讲的是二叉树的创建,我们先把二叉树(二)中提到的二叉树的设计结构提过来:

#define END '#'
typedef char ElemType;

typedef struct BtNode//BinaryTreeNode
{
	struct BtNode* leftchild;//左孩子节点
	struct BtNode* parent;//双亲指针
	struct BtNode* rightchild;//右孩子节点
	ElemType data;//数据域
}BtNode,*BinaryTree;
struct BtNode* Buynode()
{
	struct BtNode* s = (struct BtNode*)malloc(sizeof(*s));
	//struct BtNode* s=(struct BtNode*)malloc(sizeof(struct BtNode));
	if (NULL == s)
	{
		exit(0);
	}
	memset(s, 0, sizeof(*s));//对二叉树单个节点的空间进行初始化
	return s;
}

有了二叉树的结构和空间之后我们来进行二叉树的创建,创建代码如下:

BtNode* CreateTree()
{
	ElemType ch;
	BtNode* s = NULL;
	cin >> ch;
	if (ch != END)
	{
		s = Buynode();//初始化s的空间
		s->data = ch;//ch给s所指向的数据域
		s->leftchild = CreateTree();//左孩子是一颗二叉树
		s->rightchild = CreateTree();//右孩子是一颗二叉树
	}
	return s;
}

接下来我们来给出需要进行测试的主函数:

int main()
{
	BinaryTree root = NULL;
	root = CreateTree();
	InOrder(root);
	cout << endl;
	return 0;
}

当执行输入ABC##DE##F##G#H##时,运行结果如下:

在这里插入图片描述
整个分析的过程如下,由于递归调用的过程相对复杂,这个过程还是比较复杂的,如下图所示:

在这里插入图片描述

当执行输入ABC##DE##F##G#H##时,最终代码执行出来的二叉树如下图所示:
在这里插入图片描述
因此它的中序遍历为:CBEDFAGH如上面的运行结果所示。
其前序遍历和后序遍历分别为下面两种运行结果截图所示:

在这里插入图片描述

接下来我们来研究通过字符串来创建二叉树,首先看下面的代码:

BtNode* strCreateTree(const char* str)
{
	BtNode* s = NULL;
	if (str != NULL && *str != END)
	{
		s = Buynode();
		s->data = *str;
		s->leftchild = strCreateTree(++str);
		//s->leftchild = strCreateTree(++str);
		s->rightchild = strCreateTree(str+1);
		//s->rightchild = strCreateTree(str+1);
	}
	return s;
}

主函数给出其测试用例如下:

int main()
{
	char* str = "ABC##DE##F##G#H##";
	BinaryTree root = NULL;
	root = strCreateTree(str);
	//前序、中序、后序遍历代码见二叉树(二)
	InOrder(root);
	cout << endl;
	PreOrder(root);
	cout << endl;
	EndOrder(root);
	cout << endl;
	return 0;
}

运行结果是下面这样的:

在这里插入图片描述
很明显我们可以看到同样都是“ABC##DE##F##G#H##”,使用键盘输入创建的二叉树和通过字符串创建的二叉树完全不相同,这就是我们在《数据结构 &分治策略与递归》中讲到的在递归调用中一般不要使用前置“++”进行操作有关。
由于递归调用的时候是每个被调用的函数都有自己对应的栈帧,当str++或者str+1的时候,他们都在自己相应的栈帧上进行++操作,遍历的Str字符串也相互之间没有关系,根本不能将同一个字符串完整遍历一遍,所以才能得到上面这样的结果。

所以我们将参数str设为“&”(相当于别名)的时候,虽然每个递归函数在不同的栈帧上进行,但他们操作的确是同一个字符串,所以上面不能将字符串完整遍历的问题得到了解决。代码修改如下:

BtNode* strCreateTree(char* &str)
{
	BtNode* s = NULL;
	if (str != NULL && *str != END)
	{
		s = Buynode();
		s->data = *str;
		s->leftchild = strCreateTree(++str);
		s->rightchild = strCreateTree(++str);
	}
	return s;
}

这样一来,我们通过字符串创建的二叉树就和第一种从键盘上读取字符创建的二叉树完全相同了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值