利用遍历序列还原二叉树
二叉树的前序、中序和后序遍历是数据结构中的基本操作,利用这些遍历序列可以唯一地还原出原始的二叉树。本文将详细讲解如何通过前序和中序遍历、后序和中序遍历来还原二叉树,并提供相应的C语言代码实现。
基本概念
在开始之前,我们需要理解三种遍历方式:
- 前序遍历(Preorder Traversal): 顺序为:根节点 -> 左子树 -> 右子树。
- 中序遍历(Inorder Traversal): 顺序为:左子树 -> 根节点 -> 右子树。
- 后序遍历(Postorder Traversal): 顺序为:左子树 -> 右子树 -> 根节点。
前序和中序遍历还原二叉树
给定一个二叉树的前序和中序遍历序列,可以唯一地还原该二叉树。具体步骤如下:
算法步骤
- 确定根节点: 前序遍历的第一个元素是根节点。
- 划分左右子树: 在中序遍历中找到根节点的位置,其左侧的元素属于左子树,右侧的元素属于右子树。
- 递归构建左右子树: 使用相应的前序和中序序列递归构建左子树和右子树。
公式表示
设前序遍历为,中序遍历为,则:
- 根节点为。
- 在中序遍历中找到的位置,设为,则:
- 左子树的中序遍历为
- 右子树的中序遍历为
- 左子树的前序遍历为
- 右子树的前序遍历为
C语言代码实现
#include <stdio.h>
#include <stdlib.h>
// 定义二叉树节点结构
typedef struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;
// 创建新节点
TreeNode* newNode(int val) {
TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode));
node->val = val;
node->left = node->right = NULL;
return node;
}
// 前序和中序构建二叉树的递归函数
TreeNode* buildTreePreIn(int* preorder, int preorderSize, int* inorder, int inorderSize) {
if (preorderSize == 0 || inorderSize == 0) {
return NULL;
}
int rootVal = preorder[0];
TreeNode* root = newNode(rootVal);
int rootIndexInorder;
for (rootIndexInorder = 0; rootIndexInorder < inorderSize; ++rootIndexInorder) {
if (inorder[rootIndexInorder] == rootVal) {
break;
}
}
root->left = buildTreePreIn(preorder + 1, rootIndexInorder, inorder, rootIndexInorder);
root->right = buildTreePreIn(preorder + 1 + rootIndexInorder, preorderSize - 1 - rootIndexInorder, inorder + rootIndexInorder + 1, inorderSize - 1 - rootIndexInorder);
return root;
}