📅  最后修改于: 2023-12-03 15:06:33.528000             🧑  作者: Mango
在计算器中,我们经常需要构造一个表达式的二叉树。常见的二叉树构造方法有从中序和后序遍历构造和从中序和前序遍历构造。这里我们介绍一种从中序和前序遍历构造二叉树的方法。
从中序和前序遍历构造二叉树的算法分为递归和非递归两种。
递归算法的实现非常简单,我们只需要先在前序遍历中找到根节点的位置,然后在中序遍历中找到根节点的位置,根据中序遍历的性质,根节点左边的所有节点都在根节点的左子树中,右边的所有节点都在根节点的右子树中。然后我们递归地处理左子树和右子树即可。
非递归算法需要使用一个栈来保存节点。我们首先将根节点入栈,然后开始循环。我们先从前序遍历中取出一个节点,判断它是否是当前栈顶节点的左子节点,如果是,我们将新节点入栈。如果不是左子节点,我们需要不断弹出栈顶元素,直到找到一个节点,使得新节点是它的右子节点,然后将新节点入栈。
下面是从中序和前序遍历构造二叉树的 TypeScript 代码实现。
class TreeNode {
val: number;
left: TreeNode | null;
right: TreeNode | null;
constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
this.val = (val===undefined ? 0 : val);
this.left = (left===undefined ? null : left);
this.right = (right===undefined ? null : right);
}
}
function buildTree(preorder: number[], inorder: number[]): TreeNode | null {
if (preorder.length === 0 || inorder.length === 0) {
return null;
}
const rootVal = preorder[0];
const root = new TreeNode(rootVal);
const rootIndex = inorder.indexOf(rootVal);
const leftInorder = inorder.slice(0, rootIndex);
const rightInorder = inorder.slice(rootIndex + 1);
const leftPreorder = preorder.slice(1, rootIndex + 1);
const rightPreorder = preorder.slice(rootIndex + 1);
root.left = buildTree(leftPreorder, leftInorder);
root.right = buildTree(rightPreorder, rightInorder);
return root;
}
这是一个递归算法实现的 TypeScript 代码。我们首先判断是否有节点,如果没有就返回 null。然后我们从前序遍历中取出根节点的值,创建一个新的节点。我们在中序遍历中找到根节点的位置,计算左子树和右子树的中序遍历和前序遍历,递归地处理左子树和右子树,并设置根节点的左右子树。最后返回根节点即可。
从中序和前序遍历构造二叉树在计算器的表达式求值中非常有用。通过递归或非递归算法,我们可以快速构造一棵二叉树,帮助我们进行表达式求值。通过 TypeScript 代码实现,我们不仅可以更好地理解算法,而且可以在实际开发中使用该算法。