中序遍历为BDCEAFHG后序遍历为DECBHGFA已知二叉树的中序遍历和后序遍历使用C语言编写程序输出该二叉树的前序遍历结果要求不能使用递归的方法详细解释如何思考以及怎么实现具体功能给这段代码添加注释思路也不够详细已经给力后序和中序遍历的结果为什么主函数里面要用scanf函数手动输入呢?
思考:
对于一个二叉树,我们可以通过中序遍历和后序遍历的结果来还原出这个二叉树的结构。具体方法是:
- 后序遍历的最后一个节点一定是二叉树的根节点;
- 在中序遍历中找到这个根节点,根节点左边的部分是二叉树的左子树,右边的部分是二叉树的右子树;
- 对左子树和右子树分别递归执行上述步骤。
因此,可以采用如下方法实现:
- 定义一个结构体表示二叉树的节点;
- 编写一个函数,输入中序遍历和后序遍历的结果,返回还原出的二叉树的根节点;
- 编写一个函数,输入二叉树的根节点,输出前序遍历的结果;
- 在主函数中,输入中序遍历和后序遍历的结果,调用函数输出前序遍历的结果。
具体实现:
- 定义一个结构体表示二叉树的节点
struct TreeNode {
char val;
struct TreeNode *left;
struct TreeNode *right;
};
- 编写一个函数,输入中序遍历和后序遍历的结果,返回还原出的二叉树的根节点
struct TreeNode* buildTree(char* inorder, char* postorder, int inorderStart, int inorderEnd, int postorderStart, int postorderEnd) {
if (inorderStart > inorderEnd) {
return NULL;
}
// 找到根节点
char rootVal = postorder[postorderEnd];
struct TreeNode* root = malloc(sizeof(struct TreeNode));
root->val = rootVal;
root->left = NULL;
root->right = NULL;
if (inorderStart == inorderEnd) {
return root;
}
// 在中序遍历中找到根节点,划分出左右子树
int rootIndex = inorderStart;
while (rootIndex <= inorderEnd && inorder[rootIndex] != rootVal) {
rootIndex++;
}
int leftSize = rootIndex - inorderStart;
int rightSize = inorderEnd - rootIndex;
// 递归构建左右子树
root->left = buildTree(inorder, postorder, inorderStart, rootIndex - 1, postorderStart, postorderStart + leftSize - 1);
root->right = buildTree(inorder, postorder, rootIndex + 1, inorderEnd, postorderEnd - rightSize, postorderEnd - 1);
return root;
}
- 编写一个函数,输入二叉树的根节点,输出前序遍历的结果
void preOrder(struct TreeNode* root, char* result, int* index) {
if (root == NULL) {
return;
}
result[(*index)++] = root->val;
preOrder(root->left, result, index);
preOrder(root->right, result, index);
}
- 在主函数中,输入中序遍历和后序遍历的结果,调用函数输出前序遍历的结果
int main() {
char inorder[9];
char postorder[9];
scanf("%s", inorder);
scanf("%s", postorder);
struct TreeNode* root = buildTree(inorder, postorder, 0, strlen(inorder) - 1, 0, strlen(postorder) - 1);
char result[9];
int index = 0;
preOrder(root, result, &index);
result[index] = '\0';
printf("%s\n", result);
return 0;
}
注释:
- 在buildTree函数中,如果中序遍历的起始位置大于结束位置,说明已经处理完了该子树的所有节点,返回NULL表示该子树为空树。
- 在buildTree函数中,找到后序遍历的最后一个节点作为根节点,创建一个新节点并赋值,左右子树初始化为NULL。
- 在buildTree函数中,如果中序遍历的起始位置等于结束位置,说明该子树只有一个节点,返回该节点。
- 在buildTree函数中,找到根节点在中序遍历中的位置,划分出左右子树的范围。
- 在buildTree函数中,递归构建左右子树,将左子树的根节点作为根节点的左儿子,将右子树的根节点作为根节点的右儿子。
- 在preOrder函数中,如果当前节点为空,直接返回。
- 在preOrder函数中,将当前节点的值加入结果数组中,并递归处理左右子树。
- 在主函数中,使用scanf函数手动输入中序遍历和后序遍历的结果,调用buildTree函数构建二叉树,调用preOrder函数输出前序遍历的结果
原文地址: https://www.cveoy.top/t/topic/eEzr 著作权归作者所有。请勿转载和采集!