二叉树已知先序&中序求后序

#pragma once;
#include <iostream>

using namespace std;

//************************** 先序&中序==>>后序 ***************************//
/*
 * 在中序序列里查找ele的下标
 * 返回下标
 */
template <class _Ty>
int findPos(_Ty* data, int left, int right, _Ty ele)
{
	for (int i = left; i <= right; ++i)
		if (ele == data[i]) return i;
	return -1;
}

/*
 * 由先序,中序确定二叉树的后序
 */
template <class _Ty>
void preInor_post(_Ty* pre, int& preLeft,  int preRight,
				 _Ty* inor, int  inorLeft, int inorRight,
				 _Ty* post, int& postLeft, int postRight)
{
	if (preLeft > preRight || inorLeft > inorRight)
	{
		return;
	}

	int curInorPos = findPos<_Ty>(inor, inorLeft, inorRight, pre[preLeft]);
	if (-1 == curInorPos)
	{
		return;
	}
	int curPrePos = preLeft;
	++preLeft;
	preInor_post<_Ty>(pre, preLeft, preRight,
					  inor, inorLeft, curInorPos - 1,
					  post, postLeft, postRight);
	preInor_post<_Ty>(pre, preLeft, preRight,
					  inor, curInorPos + 1, inorRight,
		              post, postLeft, postRight - 1);
	post[postLeft++] = pre[curPrePos];
	
	return;
}

/*
 * 用户接口
 */
template <class _Ty>
void preInor_post(_Ty* pre, _Ty* inor, _Ty* post, int n)
{
	int preLeft = 0;
	int postLeft = 0;
	preInor_post<_Ty>(pre,  preLeft, n - 1,
					  inor, 0, n - 1,
					  post, postLeft, n - 1);
}

如中序为:bdac 后序为:dbca

    则程序可以求出先序为:abdc 。此种题型为数据结构常考题型。
算法思想:后序遍历树的规则为左右中,则说明最后一个元素必为树的根节点,比如上例中的a就为根节点,由于中序遍历为:左中右,再根据根节点a,我们就可以知道,左子树包含元素为:db,右子树包含元素:c,再把后序进行分解为db和c(根被消去了),然后递归的进行左子树的求解(左子树的中序为:db,后序为:db),递归的进行右子树的求解(即右子树的中序为:c,后序为:c)。如此递归到没有左右子树为止。

//************************** 后序&中序==>>先序 ***************************//
/*
 * 由后序,中序确定二叉树的先序
 */
template <class _Ty>
void postInor_pre(_Ty* post, int postLeft, int postRight,
				  _Ty* inor, int inorLeft, int inorRight,
				  _Ty* pre,	 int& preLeft, int preRight)
{
	int cur = 0;
	if (postLeft > postRight || inorLeft > inorRight
		|| -1 == (cur = findPos<_Ty>(inor, inorLeft, inorRight, post[postRight])))
	{
		return;
	}
	
	pre[preLeft++] = post[postRight]; // 存储后序序列的当前结点
	postInor_pre<_Ty>(post, postLeft, postLeft + cur - 1 - inorLeft,
					  inor, inorLeft, cur - 1,
					  pre, preLeft, preRight);
	postInor_pre<_Ty>(post, postLeft + cur - inorLeft, postRight - 1,
					  inor, cur + 1, inorRight,
					  pre, preLeft, preRight);
}

/*
 * 用户接口
 */
template <class _Ty>
void postInor_pre(_Ty* post, _Ty* inor, _Ty* pre, int n)
{
	int preRight = 0;
	postInor_pre<_Ty>(post, 0, n - 1,
					  inor, 0, n - 1,
					  pre, preRight, n - 1);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值