根据前序和中序遍历存储二叉树的一种方法

二叉树的建立可以通过带空指针的遍历序列建立,例如有如下二叉树。
bt
其三种遍历序列分别为:

  • DLR: ABDFGCEH
  • LDR: BFDGACEH
  • LRD: FGDBHECA

那么可以通过带空节点的前序序列AB#DF##G##C#E#H##(其中‘#’表示空节点)来创立并使用递归输入存储二叉树。

有时候需要通过两个无空节点的遍历序列来确立二叉树,例如上树中的DLR和LDR序列,这里考虑的一种方法便是将给定的前序:“ABDFGCEH” 和中序:“BFDGACEH"转化为带空节点的前序列"AB#DF##G##C#E#H##”。由此以来便可以将问题转化为带空节点的前序序列输入。而这种输入方式简单易懂,只需要考虑如何进行中间过程的转化即可。

(这里以前序和中序序列转化为前序带空节点为例)
想想根据人的思维是如何通过两个序列来确定一颗二叉树的,然后将这个思维过程加以改造形成代码即可。

  • 通常我们会将前序每一个(字符串遍历)字符与中序进行查找对比。
    在这里插入图片描述
    相应地可以将中序分割成如下两部分,
    在这里插入图片描述
    而这个中序序列便可以表示成一个如下图的形式。
    在这里插入图片描述
    继续依据前序字串的下个字符,将其在中序字串也就是相应子树进行划分。
    在这里插入图片描述
    在这里插入图片描述
    这样不断往复循环,直到形成一颗真正的二叉树。

注:有时可能会出现某一子树为空的情况,例如:
在这里插入图片描述
在这里插入图片描述
这两种情况分别对应中序序列的"ACEH" 和"BFDGA"。

至此,可以将上述过程其归结为这样几步(使用字符向量或字符串存储最终结果):

  1. 遍历前序字符串
  2. 将指针在前序中所指的字符入队
  3. 如果该字符在中序序列中左侧无子符或左侧字符在队中已存在:’#'入队。
  4. 如果该字符在中序序列中右侧字符在队中已存在:’#'入队;如果右侧无子符:标识符flag为true
  5. 重复步骤1~4直到将前序字串全部遍历完成
  6. 如果flag为true:’#'入队。
  7. 返回空节点的前序序列字符串。

样例代码:

//bintree为自定义二叉树类。
string bintree::decode(string dlr, string ldr)  
{
	bool flag = false;		//标识符
	unsigned int si, si2;
	string str = "";
	
	for (si = 0; si < dlr.size(); si++)
	{
		str += dlr[si];
		si2 = ldr.find(dlr[si]);
		
		if (si2 == 0)
			str += '#';
		else if (str.find(ldr[si2 - 1]) != string::npos)
			str += '#';
		if (si2 + 1 == ldr.size())
			flag = true;
		else if (str.find(ldr[si2 + 1]) != string::npos)
			str += '#';
	}
	if (flag == true)
		str += '#';
	return str;
}

之后将函数返回值str按照前序空节点递归方式创建二叉树即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值