/** * 问题描述: * 根据一颗二叉树的前序和中序遍历结果,重构这颗二叉树并输出后序遍历结果 */ #include <iostream> using namespace std; typedef struct node { int value; struct node *left; struct node *right; }NODE; NODE *root; //节点分配函数 NODE *malloc_NODE(int value){ NODE *p = NULL; p = (NODE *)malloc(sizeof(NODE)); p->value = value; p->right = NULL; p->left = NULL; return p; } /** * 每次递归根节点已经创建好,我们的任务就是递归创建左子树和右子树 * 从图中可以看到: * 左子树的前序和中序的起始指针很容易找到,但是右子树的 * 前序和中序的起始指针需要知道左子树的长度才行。 * 此外我们还需要维护一个子树的长度tLen,以便知道当前递归是否应该结束。 */ void rebuild_tree(NODE *root, //当前子树根节点 int *pre, //当前子树先序序列起始指针 int *in, //当前子树中序序列起始指针 int tLen) //当前子树长度(节点个数) { /** * 首先根据中序序列求出"左子树的长度"和"右子树的长度" * * Then: * 左子树"前序起始点" = 当前前序序列起始点 + 1; * 左子树"中序起始点" = 当前中序序列起始点; * * 右子树"前序起始点" = 当前前序序列起始点 + 左子树长度 + 1; * 右子树"中序起始点" = 当前中序起始点 + 左子树长度 + 1; */ //求出根节点在中序序列中的索引(根据这个索引值求左右子树长度) int root_value = *pre; int root_index = 0; int *p = in; for(int i=0;i<tLen;i++){ if(*p++ == root_value) break; root_index++; } //求解左子树和右子树的长度 int lLen = root_index; int rLen = tLen-root_index-1; //递归左子树 if(lLen != 0){ root->left = malloc_NODE(pre[1]); rebuild_tree(root->left, pre+1, in, lLen); } else{ root->left = NULL; } //递归右子树 if(rLen != 0){ root->right = malloc_NODE(pre[lLen+1]); rebuild_tree(root->right, pre+lLen+1, in+lLen+1, rLen); }else{ root->right = NULL; } } //前序遍历输出 void printBST(NODE *node){ if(node != NULL){ cout<<node->value<<endl; printBST(node->left); printBST(node->right); } } #define M 5 int main(){ int pre[M] = {1,2,4,5,3}; int in[M] = {4,2,5,1,3}; root = malloc_NODE(pre[0]); //以root为根节点,按照pre和in两个序列重构二叉树 rebuild_tree(root, pre, in, M); printBST(root); return 0; }