树的括号表示

1、树的线性表示

    树型结构和线性结构的主要区别在于树型结构具有分支性和层次性。使用树的遍历操作,可以将树中的结点按照规定的顺序排成一个线性序列;然而仅凭借树的某种遍历序列有时无法唯一地确定一棵树,但只要在遍历序列的基础上增加一些附加信息便可以唯一地确定一棵树,从而得到树的线性表示。树的线性表示便于树的输入、输出,同时在存储时也比较节省空间。

2、树的括号表示规则

(1)若树T为空树,则其括号表示为空

(2)若树T只包含一个结点,则其括号表示即为该结点本身

(3)若树T由根结点A和它的m棵子树T1,T2,...,Tm构成,则其括号表示为:A(T1的括号表示,T2的括号表示,... ,Tm的括号表示)

其中,子树的括号表示同样应该遵循以上规则

上图中树的括号表示为 A(B,C(F,G,H),D,E(I,J))

实现方法如下:

(1)从左到右扫描树的括号表示;

(2)每当遇到左括号时,其前一个结点进栈,并读入下一个符号;

(3)每当遇到右括号时,栈顶元素出栈。说明以栈顶元素为根的树(子树)构造完毕,此时若栈为空,算法结束,否则读入下一个符号

(4)每当遇到结点时,则它一定为栈顶元素的子女,将其挂到栈顶元素的某子女位置上,并读入下一个符号;

(5)每当遇到“,”,则略过该符号,并读入下一个符号。


通过一个例子说明具体实现代码如下:

设一棵完全二叉树为1(2(4(8,9),5(10,11)),3(6(12),7)) ,图形表示为

程序运行结果为:

实现代码:

//以括号表示法构建二叉树
void BrackToTree(char* line,BinaryTree* p)
{
	int i=0;
	int j=0;
	//申请结点存储缓冲数组
	char *buff = (char*)malloc((strlen(line)+1)*sizeof(char));
	//定义并初始化栈
	SqStack* pst = (SqStack*)malloc(sizeof(SqStack));
	InitStack(pst);
	BiTNode* pbt = NULL;//前一结点地址
	while(ExtractNodeFromStr(line,&i,&j,buff))//遇到'\n'或'\0'时退出构建树
	{
		if(strcmp(buff,"(") == 0)
		{
			Push(pst,pbt);//前一结点入栈,作为子树根结点
		}
		else if(strcmp(buff,")") == 0)
		{
			Pop(pst);//栈顶元素出栈,表示一棵子树构建完毕
		}
		else if(strcmp(buff,",") == 0)
		{
			;//无作为
		}
		else//字符串
		{
			pbt = (BiTNode*)malloc(sizeof(BiTNode));//新建结点,更新前一结点
			pbt->data = atoi(buff);//更新新建结点数据
			pbt->lchild = NULL;
			pbt->rchild = NULL;
			if(StackEmpty(pst))//栈空
			{
				p->root = pbt;//直接作为树根结点
			}
			else
			{
				//printf("在父结点%d下,插入结点%d\n",(GetTop(pst))->data,pbt->data);
				InsertChild(GetTop(pst),pbt);//将新建结点作为栈顶结点的子结点
			}	
		}
	}	
	//销毁栈
	DestroyStack(pst);
	//销毁缓冲数组
	free(buff);
}



### 二叉括号表示法 二叉括号表示法是一种通过字符串形式描述二叉结构的方法。它利用嵌套的括号来表达节点之间的父子关系以及左右子的关系[^1]。 #### 基本规则 - 如果一棵二叉为空,则用空格或者特殊字符(如 `#` 或者 `-`)表示。 - 对于非空的二叉,根节点的数据放在最前面,后面紧跟两个括号分别表示左子和右子的内容。 - 左子和右子按照相同的规则递归定义。 例如,对于如下的一棵简单二叉: ``` A / \ B C / D ``` 它的括号表示可以写成: `A(B(),C(D(),))` 解释: - 根节点为 `A`。 - 左子为 `B()`,其中 `B` 是根节点,而其左右子均为空。 - 右子为 `C(D(),)`,其中 `C` 的左子为 `D()`,右子为空。 如果允许省略空子的部分括号,也可以简化为: `A(B,C(D))` 这种表示方式的优点是可以清晰地展示二叉的层次结构,并且便于程序化解析和重建二叉[^2]。 #### 使用代码构建二叉 以下是基于括号表示法创建二叉的一个示例代码片段: ```cpp #include <iostream> #include <stack> using namespace std; typedef struct Node { char data; Node* lchild; Node* rchild; } BTNode; // 创建二叉函数 void createTreeByBracketNotation(string str, int& index, BTNode*& root) { if (index >= str.length()) return; if (str[index] == '#') { // 空节点处理 root = nullptr; index += 2; // 跳过 ',' return; } root = new BTNode(); root->data = str[index++]; // 当前节点数据 if (str[index] == '(') { // 存在左子 index++; // 跳过'(' createTreeByBracketNotation(str, index, root->lchild); } if (str[index] == ')') { // 结束当前层 index++; } if (str[index] == '(') { // 存在右子 index++; // 跳过'(' createTreeByBracketNotation(str, index, root->rchild); } } ``` 此代码实现了从括号表示法字符串中还原二叉的功能。输入字符串遵循括号表示法的规则,逐字符读取并递归构造对应的二叉节点[^2]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值