我在看leetcode上的这个问题。给定两个数组,按序和按序,需要构造一个二叉树。我得到了问题的通解。
预排序遍历访问根、左和右,因此左子级将是当前预排序节点索引1。根据该值,您可以使用inorder数组知道树左侧有多少个节点。在答案中,用于找到合适孩子的公式是“preStart inIndex-inStart 1”。
我不想记住这个公式,所以我想知道是否有证据证明这一点?我浏览了那里的讨论板,但仍然缺少一个链接。
>
在Python中,我们还可以使用pop(0)
来解决这个问题,尽管这效率很低(但它会通过)。
为了降低效率,我们可以将deque()
与popleft()
一起使用,但是不能在LeetCode上使用,因为我们无法控制树。
class Solution:
def buildTree(self, preorder, inorder):
if inorder:
index = inorder.index(preorder.pop(0))
root = TreeNode(inorder[index])
root.left = self.buildTree(preorder, inorder[:index])
root.right = self.buildTree(preorder, inorder[index + 1:])
return root
对于Java和C来说,就像你说的那样(没有证据),这会有点不同,但这篇文章可能会有点帮助:
public class Solution {
public static final TreeNode buildTree(
final int[] preorder,
final int[] inorder
) {
return traverse(0, 0, inorder.length - 1, preorder, inorder);
}
private static final TreeNode traverse(
final int preStart,
final int inStart,
final int atEnd,
final int[] preorder,
final int[] inorder
) {
if (preStart > preorder.length - 1 || inStart > atEnd) {
return null;
}
TreeNode root = new TreeNode(preorder[preStart]);
int inorderIndex = 0;
for (int i = inStart; i <= atEnd; i++)
if (inorder[i] == root.val) {
inorderIndex = i;
}
root.left = traverse(preStart + 1, inStart, inorderIndex - 1, preorder, inorder);
root.right = traverse(preStart + inorderIndex - inStart + 1, inorderIndex + 1, atEnd, preorder, inorder);
return root;
}
}
// The following block might slightly improve the execution time;
// Can be removed;
static const auto __optimize__ = []() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
return 0;
}();
// Most of headers are already included;
// Can be removed;
#include <cstdint>
#include <vector>
#include <unordered_map>
using ValueType = int;
static const struct Solution {
TreeNode* buildTree(
std::vector<ValueType>& preorder,
std::vector<ValueType>& inorder
) {
std::unordered_map<ValueType, ValueType> inorder_indices;
for (ValueType index = 0; index < std::size(inorder); ++index) {
inorder_indices[inorder[index]] = index;
}
return build(preorder, inorder, inorder_indices, 0, 0, std::size(inorder) - 1);
}
private:
TreeNode* build(
std::vector<ValueType>& preorder,
std::vector<ValueType>& inorder,
std::unordered_map<ValueType, ValueType>& inorder_indices,
ValueType pre_start,
ValueType in_start,
ValueType in_end
) {
if (pre_start >= std::size(preorder) || in_start > in_end) {
return nullptr;
}
TreeNode* root = new TreeNode(preorder[pre_start]);
ValueType pre_index = inorder_indices[preorder[pre_start]];
root->left = build(preorder, inorder, inorder_indices, pre_start + 1, in_start, pre_index - 1);
root->right = build(preorder, inorder, inorder_indices, pre_start + 1 + pre_index - in_start, pre_index + 1, in_end);
return root;
}
};
如果我们要在左子树中找到节点,甚至在根节点上,它会给出正确的输出,但是如果我们在右边找到任何节点,比如根->right,即节点70,它会给出错误的输出20、30、40、50、60。我知道我在哪里犯了错误,我应该如何修改代码,这样对于输入70,只有它的左子树,即,节点60是打印的。
我在研究一个重建二叉查找树的函数。我正试着先用手做。 说我有:pre-10,3,5,4,15,7,8,2,9,20 in-4,5,3,15,10,20,8,7,9,20 我弄不明白。我知道10必须是根,顺序序列中10左边的所有数字都必须在右边的子树中。 那会给我 4,5,3,15 15大于10,并且为了成为二叉查找树,左子树中的所有节点应该小于根。 这是否意味着这两个序列形成了一个无效的二叉搜索树
为了上课,我必须创建一个状态对象的二叉树,每个状态对象包括一个居民对象的二叉树,这些居民对象组织住在每个州的人。我试图在一个给定的州中搜索最老的居民;然而,居民是按字母顺序组织在树中的,这对我的搜索毫无帮助。因此,我必须遍历整个居民树,更新保存最老的人的节点,并在树被完全遍历后返回它。我已经有了代码的第一部分,但是还停留在如何写递归的剩余部分。 状态树的方法: 然后是公共“包装器”状态树方法:
中序遍历二叉树 按完全二叉树的层次遍历给出一棵二叉树的遍历序列(其中用0表示虚结点),要求输出该二叉树的深度及中序遍历该二叉树得到的序列。 输入格式: 首先输入一个整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据首先输入一个正整数n(n≤1000),代表给出的二叉树的结点总数(当然,其中可能包含虚结点)。结点编号均为正整数,且各不相同。 然后输入n个正整数,表示按完全二叉树(即第1层1
我试图使用队列的链表实现实现二叉搜索树的级别顺序遍历。 我已经检查了二叉查找树的实现,它是好的。队列的链表实现也是正确的。在这里,我试图访问节点并将其子节点排队。然后使用弹出函数实际访问节点。 这最终是通过递归调用完成的。当我运行以下代码时,我以不同的顺序获得输出。
我想对二叉树执行级别顺序遍历。因此,对于给定的树,说: 产出将是: 我知道我可以使用某种队列,但在C中递归地实现这一点的算法是什么?感谢您的帮助。