首先先序遍历的顺序是:
1.节点
2.左子树
3.右子树
中序遍历的顺序:
1.左子树
2.节点
3.右子树
后序遍历的顺序:
1.左子树
2.右子树
3.节点
因此我们很容易从后序遍历的顺序中看出,最后一个节点就是根节点
由此我们写出一个重要的函数
//传入中序遍历的数组inorder[],和后序遍历的数组postorder[]
//len代表数组的长度
node BuildTree(char* inorder,char* postorder,int len)
{
//如果数组的长度为0,则直接返回
if (len == 0)
return NULL;
//如果还剩下一个节点,那么它一定是接下来的根节点,直接连接就i行
else if (len == 1)
return creat(*postorder);
//讨论完上面两种特殊情况,接下来的节点一定是大于等于两个的
else
{
//这里我们寻找我们的根节点,也就是后续数组的最后一个节点
Tree* newnode = creat(*(postorder + len - 1));
//这里的index是为了找到根节点在中序中的位置,进而将其分为左子树和右子树
int index = 0;
for (int i = 0; i < len; i++)
{
if (*(inorder + i) == *(postorder + len - 1))
{
index = i;
break;
}
}
//这里通过index来控制传入数组的长度因此不用担心根节点以及之后的节点会影响程序的运行
newnode->left = BuildTree(inorder, postorder, index);
//这里的右子树的起点是根节点下标+1,因为在中序中,inorder+index是根节点的下标所以要+1
//而后序则不用考虑,长度len-index是不包括根节点本身的,因此还要-1
newnode->right = BuildTree(inorder + index + 1, postorder + index, len - index - 1);
return newnode;
}
}
下面是完整代码:
#include<iostream>
#include<malloc.h>
#include<string.h>
using namespace std;
typedef struct Tree
{
char data;
struct Tree* left;
struct Tree* right;
}Tree,*node;
Tree* creat(char data)
{
Tree* q = (Tree*)malloc(sizeof(Tree));
q->data = data;
q->left = NULL;
q->right = NULL;
return q;
}
node BuildTree(char* inorder, char* postorder, int len)
{
if (len == 0)
return NULL;
else if (len == 1)
return creat(*postorder);
else
{
Tree* newnode = creat(*(postorder + len - 1));
int index = 0;
for (int i = 0; i < len; i++)
{
if (*(inorder + i) == *(postorder + len - 1))
{
index = i;
break;
}
}
newnode->left = BuildTree(inorder, postorder, index);
newnode->right = BuildTree(inorder + index + 1, postorder + index, len - index - 1);
return newnode;
}
}
void preorder(Tree* S)
{
if (S == NULL)
return;
cout << S->data;
preorder(S->left);
preorder(S->right);
}
int main()
{
char inorder[50];
char postorder[50];
cin >> inorder;
cin >> postorder;
int len = strlen(inorder);
Tree* root = BuildTree(inorder, postorder, len);
preorder(root);
return 0;
}
(dalao勿喷!)