//给出先序序列,中序序列恢复出二叉树的方法
//方法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);
}