二叉树可以由中序序列和前序序列,或者中序序列和后序序列唯一还原一棵二叉树。
算法步骤:1、先序(后序)找根;2、中序分左右;3、递归还原
详细步骤:
1、建立数的结点类,有3个成员,data是char类型存放该结点的值,lchild和rchild是指针类型,用于指向该结点的左右孩子结点;
2、输入树中结点的个数,并输入先序遍历序列和后序遍历序列,用数组存储;
3、递归创建树,返回值为Node*类型,用于返回根;参数为先序序列数组、中序序列数组和数组的长度len,递归结束条件是数组长度为0;
先序找根:先序序列数组的第一个元素是根;
中序分左右:在中序序列数组中找到根的位置loc,根的左边是左子树,根的右边是右子树;
递归创建左子树,左子树的先序序列数组首地址为先序序列首地址+1,中序序列首地址不变,长度为loc;
递归创建右子树,右子树的先序序列数组首地址为先序序列首地址+1+loc,右子树的中序序列首地址为中序序列首地址+1+loc,长度为len-loc-1;
返回值为Node*类型,用于记录树根。
4、用后序遍历验证是否还原正确。
代码实现:
#include <iostream>
using namespace std;
#define max_size 100
class Node
{
public:
char data;
Node* lchild;
Node* rchild;
};
using Tree = Node*;
char pre[max_size], in[max_size];
int Input()
{
int n;
cout << "请输入结点的个数:" << endl;
cin >> n;
cout << "请输入前序序列" << endl;
for (int i = 0; i < n; i++)
{
cin >> pre[i];
}
cout << "请输入中序序列" << endl;
for (int i = 0; i < n; i++)
{
cin >> in[i];
}
return n;
}
Tree CreateTree(char* front, char* mid, int len)
{
if (len == 0)
{
return nullptr;
}
char temp = front[0]; //先序找根
int loc = 0;
for (int i = 0; i < len; i++)
{
if (mid[loc] != temp)
{
loc++;
}
} //中序分左右
Tree t = new Node; //创建新结点
t->data = temp; //根
t->lchild = CreateTree(front + 1, mid, loc);
t->rchild = CreateTree(front + loc + 1, mid + loc + 1,len - loc - 1);
return t;
}
void Prove(Node* root)
{
if (!root)
{
return;
}
Prove(root->lchild);
Prove(root->rchild);
cout << root->data << " ";
}
int main()
{
Tree t;
int n = Input();
t = CreateTree(pre, in, n);
cout << "后序序列为" << endl;
Prove(t);
return 0;
}