给出先序序列,中序序列恢复二叉树

//给出先序序列,中序序列恢复出二叉树的方法

//方法1:利用递归的方法,首先先找出根节点,然后有先序和后序的特点可知:先序序列中在根节点左边的是左子树,根节点右面的是右子树

//有此来,进行递归,便可以恢复出二叉树

//方法2:方法2中栈的利用只是来存取,节点和先序中每个数据在后序的位置,利用pos 来记录每个位置的值

//该非递归的主要思想就是在后序序列中左节点的位置在右节点之前,也就是说pos(左)<pos(右),先序序列是直接遍历下来就可以了,然后在

//后序序列中,查找每个数据的相对的位置的值,与前面的位置进行比较,来判断,该节点是左子树,还是右子树

//如果是左子树,则不断的将位置数据pos,和节点str不停的压入栈中

//如果是右子树,则将数据和节点不停的弹出栈,直到位置数据栈的栈顶元素大于当前位置数据的值,将该节点插入到该节点的右孩子节点处

//并将节点和位置数据pos全部压入栈中

//posChar(char ch,char* str)该函数是辅助函数,功能是查找ch在str中出现的位置

template<typename T>
int BinaryTree<T>::posChar(char ch, char* str)
{
	if (strlen(str) == 0)
	{
		cout << "the char* is empty" << endl;
		exit(true);
	}
	int i = 0;
	while (str[i] != '\0')
	{
		if (ch == str[i])
		{
			return i;
		}
		i++;
	}
	return -1;
}
template<typename T>
void BinaryTree<T>::DefineBinaryTree(char* preOrder, char* midOrder)
{
	if (strlen(preOrder) == 0 || strlen(midOrder) == 0)
	{
		this->root = NULL;
		return;
	}
	//记录每个与先序中节点对应的后序中的节点的位置
	int pos;
	//position,node两个栈存放的是pos,和生成的每个节点
	stack<int>position;
	stack<BinaryTreeNode<T>*>node;
	//str,ptr用于生成节点
	BinaryTreeNode<T>* str = NULL;
	BinaryTreeNode<T>* ptr = NULL;
	str = new BinaryTreeNode<T>(preOrder[0], NULL, NULL);
	this->root = str;
	pos = posChar(preOrder[0], midOrder);
	position.push(pos);
	node.push(str);
	int i = 1;
	while (preOrder[i] != '\0')
	{
		pos = posChar(preOrder[i], midOrder);
		if (pos == -1)
		{
			cout << "the match is error" << endl;
			exit(true);
		}
		str = new BinaryTreeNode<T>(preOrder[i], NULL, NULL);
		if (pos < position.top())
		{
			//当num < position.top()时,则该节点是左节点
			ptr = node.top();
			ptr->leftChild = str;
			node.push(str);
			position.push(pos);
		}
		else
		{
			while (!position.empty() && pos > position.top())
			{
				ptr = node.top();
				position.pop();
				node.pop();
			}
			ptr->rightChild = str;
			node.push(str);
			position.push(pos);
		}
		i++;
	}
}
template<typename T>
void BinaryTree<T>::simulate()
{
	char preOrder[100];
	char midOrder[100];
	cout << "input the preOrder: ";
	cin >> preOrder;
	cout << "input the midOrder: ";
	cin >> midOrder;
	int length = strlen(midOrder);
	/*this->DefineBinaryTree(this->root,preOrder,midOrder,length);*/
	this->DefineBinaryTree(preOrder, midOrder);
}
template<typename T>
void BinaryTree<T>::DefineBinaryTree(BinaryTreeNode<T>* &str, char* preOrder, char* midOrder, int length)
{
	if (length == 0)
	{
		str = NULL;
		return;
	}
	str = new BinaryTreeNode<T>(*preOrder, NULL, NULL);
	char* pStr = strchr(midOrder, str->data);
	if (pStr == NULL)
	{
		cout << "the midOrder string is wrong" << endl;
		exit(true);
	}
	int leftTreeLength = strlen(midOrder) - strlen(pStr);
	int rightTreeLength = length - leftTreeLength - 1;
	DefineBinaryTree(str->leftChild, preOrder + 1, midOrder, leftTreeLength);
	DefineBinaryTree(str->rightChild, preOrder + leftTreeLength + 1, pStr + 1, rightTreeLength);
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值