解题代码+注释:
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 60
typedef struct Node
{
char data;
struct Node* lchild, *rchild;
}Node;
Node* init(char data)
{
Node* node = (Node*)malloc(sizeof(Node));
node->lchild = NULL;
node->rchild = NULL;
node->data = data;
return node;
}
Node* build(char pre_str[], char in_str[], int len)//len指中序序列(片段)的长度
{
Node* p = init(pre_str[0]);
//strchr()在字符串str中找字符ch第1次出现的位置,找到后函数返回一个指向该位置的指针。
//如果该字符并不存在与字符串中,函数就返回一个NULL指针。因此需要再减去数组首元素的地址
int pos = strchr(in_str, pre_str[0]) - in_str;//pos是头结点到中序序列头部的距离
if (pos > 0)//说明头结点到中序序列头部间还有节点,这些节点即头结点的左孩子
{
p->lchild = build(pre_str + 1, in_str, pos);
//pre_str + 1,指前序序列往后递归该头结点的左子树
//pos指这次递归的中序序列是头节点出现位置的左边,即头结点的左子树
}
if (pos < len - 1)//说明头结点到中序序列尾部间还有节点,这些节点即头结点的右孩子
{
p->rchild = build(pre_str + pos + 1, in_str + pos + 1, len - pos - 1);
//pre_str + pos + 1,头节点的位置加上左子树节点的个数(pos+1),即递归头结点的右子树,这次还需要多向右一个头节点,因此是pos+1
//in_str + pos + 1,同理,是遍历头结点的右子树
//len - pos - 1,后序序列该节点的右子树的长度
}
return p;
}
void postorder(Node* node)
{
if (node->lchild != NULL) postorder(node->lchild);
if (node->rchild != NULL) postorder(node->rchild);
cout << node->data;
}
void image_postorder(Node* node)
{
if (node->rchild != NULL) image_postorder(node->rchild);
if (node->lchild != NULL) image_postorder(node->lchild);
cout << node->data;
}
int main()
{
char pre_str[MAX], in_str[MAX];
cin >> pre_str >> in_str;
Node* root = build(pre_str, in_str, strlen(in_str));
postorder(root);
cout << endl;
image_postorder(root);
return 0;
}