由中序与前序、中序与后序重建二叉树

由中序与前序、中序与后序重建二叉树

<span style="font-size:14px;">//节点类型
template<class T>
class TNode
{
public:
	TNode() { lchild = rchild = parent = nullptr; };
	T data;
	TNode<T>* lchild, *rchild, *parent;
};</span>


一:已知前序与中序。
方法很简单,前序第一个节点为根节点,在中序中找到该节点。该位置左为左子树,右边为右子树。然后递归创建。
template<class T>
TNode<T>* TriTree<T>::MakeRootByPre(const string& Pre, const int PreBegin, const int PreEnd,
	const string& In, const int InBegin, const int InEnd)
{
	assert("" != Pre || "" == In);
	if (!(PreBegin >= 0 && PreEnd >= 0 && InBegin >= 0 && InEnd >= 0))
	{
		return nullptr;
	}
	if (PreBegin > PreEnd || InBegin > InEnd ||
		(unsigned)PreEnd >= Pre.length() || (unsigned)InEnd >= In.length())
	{
		return nullptr;
	}
	char ChRoot = Pre[PreBegin];
	TNode<T>* pRoot = new TNode<T>();
	//暂时不考虑父节点  并且遍历结果以字符串显示
	pRoot->data = ChRoot;
	int nPos = FindInString(In,ChRoot,InBegin,InEnd);
	if (-1 == nPos)
	{
		return nullptr;
	}
	int CountOfLeftTree = nPos - InBegin;//左子树节点个数
	pRoot->lchild = MakeRootByPre(Pre,PreBegin+1,PreBegin+ CountOfLeftTree,
		In,InBegin,nPos-1);//递归创建左子树
	pRoot->rchild = MakeRootByPre(Pre,PreBegin+CountOfLeftTree+1,PreEnd,
		In,nPos+1,InEnd);
	return pRoot;
}
二:由后序与中序重建,方法与一相似,有节点在后序遍历末尾而已。
template<class T>
TNode<T>* TriTree<T>::MakeRootByPost(const string& StrPost, const int PostBegin, const int PostEnd,
	const string& StrIn, const int InBegin, const int InEnd)
{
	//考虑父节点时可以再传一个参数即可
	//也可以写一个重建函数连接父节点
	assert(""!=StrPost&&""!=StrIn);
	if (PostBegin < 0 || PostEnd < 0 || InBegin<0 || InEnd<0 ||
		PostBegin>PostEnd || InBegin>InEnd||
		PostEnd>=StrPost.length()||InEnd>=StrIn.length())
	{
		return nullptr;
	}
	TNode<T>* pRoot = new TNode<T>();
	assert(nullptr!=pRoot);
	char ChRoot = StrPost[PostEnd];
	pRoot->data = ChRoot;
	int nPos = FindInString(StrIn, ChRoot,InBegin,InEnd);
	if (-1 == nPos)
	{
		return nullptr;
	}
	int CountOfLeftTree = nPos - InBegin;
	pRoot->lchild = MakeRootByPost(StrPost,PostBegin,PostBegin+CountOfLeftTree-1,
		StrIn,InBegin,nPos-1);//注意边界
	pRoot->rchild = MakeRootByPost(StrPost,PostBegin+CountOfLeftTree,PostEnd-1,
		StrIn,nPos+1,InEnd);
	return pRoot;
}
思想都比较简单,个人认为代码写得比较清晰,大家可以看完代码,了解思想后,再手撸一遍。
template<class T>
int TriTree<T>::FindInString(const string& In, const char ChRoot, const int nBegin, const int nEnd)
{
	//参数为闭区间
	assert("" != In);
	if (!(nBegin >= 0 && nEnd >=0 && nEnd >= nBegin&&nEnd < (int)In.length()))
	{
		return -1;
	}
	for (int i = nBegin; i <= nEnd; ++i)
	{
		if (ChRoot == In[i])
		{
			return i;
		}
	}
	return -1;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值