hiho_1049 二叉树遍历
题目大意
给出一棵二叉树的前序和中序遍历结果,求出后序遍历的结果。保证二叉树中节点值均不相同。
分析
通过前序和中序遍历的结果,我们可以构建出二叉树,若构建出二叉树,则后序遍历的结果很容易求出(当然递归方法很容易)。主要是二叉树的构建。
二叉树类型非常适合用递归进行求解,所以考虑通过递归的方式来建立二叉树。由前序和中序遍历性质可知,前序遍历的第一个值就是二叉树中根节点的值,因此可以将之作为根节点,然后从中序遍历结果中找到对应的值(保证树中所有节点值均不相同)所在的位置A,则A左边的就是A的左子树中的节点(根据中序遍历的性质可知)。每次从前序数组中找到一个新的节点,可以将中序数组分割出左半部分.....
递归求解,主要是状态参数的选取。前序遍历结果数组pre_order,中序遍历结果数组middle_order, 选择中序遍历的左边界 middle_left_index(表示当前递归构建出来的子树节点们在中序遍历数组中的左边界), 中序遍历的右边界 middle_right_index(表示当前递归构建出来的子树节点们在中序遍历数组中的左边界),pre_index 表示当前前序遍历数组的索引(用于选择根节点,且将中序遍历数组分割出左部分)。
实现
#pragma once #pragma execution_character_set("utf-8") // 本文件为utf-8 编码格式 #include<iostream> #include<stdio.h> #include<string.h> using namespace std; struct TreeNode{ char val; TreeNode* left; TreeNode* right; TreeNode(char c = '0') :val(c), left(NULL), right(NULL){}; }; TreeNode* BuildTree(char* pre_order, char* middle_order, int& pre_index, int middle_left_index, int middle_right_index){ if (middle_left_index >= middle_right_index) return NULL; if (pre_order[pre_index] == '\0') return NULL; char root_val = pre_order[pre_index++]; int middle_root_index = middle_left_index; while (middle_order[middle_root_index] != '\0' && middle_order[middle_root_index] != root_val) middle_root_index++; if (middle_order[middle_root_index] == '\0') return NULL; TreeNode* root = new TreeNode(root_val); root->left = BuildTree(pre_order, middle_order, pre_index, middle_left_index, middle_root_index); root->right = BuildTree(pre_order, middle_order, pre_index, middle_root_index + 1, middle_right_index); return root; } void PostOrderTravel(TreeNode* root){ if (!root) return; PostOrderTravel(root->left); PostOrderTravel(root->right); printf("%c", root->val); } int main(){ char pre_order[27]; char middle_order[27]; scanf("%s", pre_order); scanf("%s", middle_order); int pre_index = 0; TreeNode* root = BuildTree(pre_order, middle_order, pre_index, 0, strlen(middle_order)); PostOrderTravel(root); return 0; }