根据前序和中序遍历确定后序遍历

基于后序遍历的二叉树构造算法
本文介绍了一种使用后序遍历序列构造二叉树的方法,通过递归实现,从序列中逐步构建树的结构。
#include <cstdio>
#include <cstring>
char str1[100],str2[100],str[100];
void Create(int n,char * str1,char * str2,char * str)
{
	if (n <= 0)
		return;
	int len = strchr(str2,str1[0]) - str2;//strchr查找根结点在中序中的位置
	Create(len,str1 + 1,str2,str);//递归构造左子树
	Create(n - len - 1,str1 + len + 1,str2 + len + 1,str + len);//递归构造右子树
	str[n - 1] = str1[0];//根据后序遍历的特点把根结点保存到最后
}
int main()
{
	while (scanf("%s%s",str1,str2) == 2)
	{
		int n = strlen(str1);
		Create(n,str1,str2,str);
		str[n] = '\0';
		printf("%s\n",str);
	}
	return 0;
}

根据二叉树的前序序遍历结果来输出后序遍历数列,可先根据前序序遍历结果构建出二叉树,再对构建好的二叉树进行后序遍历从而得到后序遍历数列。 以下是使用 C++ 实现的代码: ```cpp #include <iostream> #include <vector> using namespace std; // 定义二叉树节点结构 struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} }; // 根据前序序遍历构建二叉树 TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder, int preStart, int preEnd, int inStart, int inEnd) { if (preStart > preEnd || inStart > inEnd) { return nullptr; } // 前序遍历的第一个元素是根节点 int rootVal = preorder[preStart]; TreeNode* root = new TreeNode(rootVal); // 在中序遍历中找到根节点的位置 int rootIndexInorder = inStart; while (rootIndexInorder <= inEnd && inorder[rootIndexInorder] != rootVal) { rootIndexInorder++; } // 计算左子树的节点数量 int leftSubtreeSize = rootIndexInorder - inStart; // 递归构建左子树右子树 root->left = buildTree(preorder, inorder, preStart + 1, preStart + leftSubtreeSize, inStart, rootIndexInorder - 1); root->right = buildTree(preorder, inorder, preStart + leftSubtreeSize + 1, preEnd, rootIndexInorder + 1, inEnd); return root; } // 后序遍历二叉树 void postorderTraversal(TreeNode* root, vector<int>& result) { if (root == nullptr) { return; } postorderTraversal(root->left, result); postorderTraversal(root->right, result); result.push_back(root->val); } // 主函数,根据前序序遍历输出后序遍历数列 vector<int> preInToPost(vector<int>& preorder, vector<int>& inorder) { int n = preorder.size(); TreeNode* root = buildTree(preorder, inorder, 0, n - 1, 0, n - 1); vector<int> result; postorderTraversal(root, result); return result; } ``` 可以使用以下方式调用这个函数: ```cpp int main() { vector<int> preorder = {3, 9, 20, 15, 7}; vector<int> inorder = {9, 3, 15, 20, 7}; vector<int> postorder = preInToPost(preorder, inorder); // 输出后序遍历结果 for (int val : postorder) { cout << val << " "; } cout << endl; return 0; } ``` ### 代码解释 1. **TreeNode 结构体**:定义了二叉树的节点结构,包含节点的值以及左右子节点指针。 2. **buildTree 函数**:根据前序序遍历结果递归构建二叉树。前序遍历的第一个元素是根节点,在中序遍历中找到根节点的位置,从而划分出左子树右子树的节点集合,再递归构建左右子树。 3. **postorderTraversal 函数**:对构建好的二叉树进行后序遍历,将遍历结果存储在 `result` 向量中。 4. **preInToPost 函数**:调用 `buildTree` 函数构建二叉树,再调用 `postorderTraversal` 函数进行后序遍历,最终返回后序遍历数列。 ### 复杂度分析 - **时间复杂度**:$O(n)$,其中 $n$ 是二叉树的节点数。每个节点都会被访问一次。 - **空间复杂度**:$O(n)$,主要是递归调用栈的空间开销,最坏情况下二叉树退化为链表,递归深度为 $n$。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值