【问题标题】:Minimum value not in a binary tree?最小值不在二叉树中?
【发布时间】:2013-01-11 11:47:18
【问题描述】:

我正在尝试找到一种方法来找到不在二叉搜索树中的最小正数 ([0, INT_MAX))(最大整数)值。树具有所有正整数。我正在考虑沿着树的左侧向下移动。然后创建一个结构体值struct { int data; bool found; };,如果是最小值,我返回t/f。

我通过遍历左侧来做到这一点,如果root->data + 1 > left->data,则返回

左->数据+1

,否则向右。那么如果

root->data + 1 data

,然后是return root->data + 1。否则返回root->data or right->data,如果right 不为null,找到的值为false。我还必须考虑树中的最小值是否不为 0,然后返回 0。我不确定这是否是最好的方法。

感谢您的帮助。

编辑:对不起,我昨晚写的,当时我真的很累。我在循环中使用它,因此每次将其放入数组中会占用太多时间。我使用的是二叉搜索树,因此每次通过循环只需插入和删除 1 次即可完成,用最少的时间找到不在树中的最小值。

【问题讨论】:

  • 什么是max_int?这是您的程序定义的一些数字,还是可能的最大整数(即std::numeric_limits<int>::max)?
  • 二叉树还是二叉搜索树?
  • 这是一个二叉搜索树。而max_int实际上是INT_MAX,它是最大可能的整数。

标签: c++ c algorithm binary-tree


【解决方案1】:

您可以按照以下步骤操作:

  • 声明一个大小为max_int、类型为bool的数组,并用false初始化所有元素。

    bool found[max_int] = {}; //it initializes the array with false!
    //assumming `max_int` is a constant expression.
    //else you can use `std::vector<bool>` or `std::vector<char>`.
    
  • 使用BFS 或DFS 或任何适合您的方式遍历树。对于树中的每个值v,将索引v 处的数组更新为:

    found[v] = true; //it means value `v` is found in the tree!
    

完成后。 found[i] 为 false 的最低索引 i 是您要查找的值。也就是说,i 是不在树中的最小值。

请注意,二叉树和二叉搜索树之间是有区别的。我的解决方案适用于二叉树,尽管它将也适用于二叉搜索树。只是在二叉搜索树的情况下,您可以找到更优的解决方案,例如在遍历时您可以忽略具有更大值的分支。我希望你自己能做到。

【讨论】:

  • “声明一个大小为 max_int 的 bool 类型的数组” - 如果 max_int 是 INT_MAX,那么它在典型的 32 位实现中不起作用。修复(除了获得 64 位处理器)留给读者作为练习......
  • @SteveJessop:我很困惑。如果max_int 是INT_MAX,为什么它不起作用? @读者,称之为内存方面的修复或改进,可以使用bit代替bool。
  • 因为在典型的 32 位实现中,您无法创建大小为 INT_MAX 的数组。好的,所以也许它只是地址空间的一半,而不是全部,所以原则上它可以工作。在实践中,操作系统限制了哪些地址范围可用于在程序中创建的对象。
  • 不是真的,这取决于你把它放在哪里。自动变量(堆栈)通常比静态存储持续时间(全局)或动态分配更受限制。当您的分配不安全时会发生什么情况:对于动态分配,您会遇到分配失败,对于自动分配,您会遇到未定义的行为,对于全局,我不记得发生了什么,但最坏的情况应该是程序无法运行,可能是来自操作系统/加载器的模糊消息。
  • 哦,C++11 的附录 B 建议实现应该能够创建大小为 262144 字节的对象。这个限制太小了,没有太多实际用途。
【解决方案2】:

假设您的树不包含重复值,您可以按顺序遍历您的树。第一个访问节点的期望值为0。每个后续访问节点的期望值都比最后一个访问节点大1。如果您遇到与预期值不同的节点,那么预期值就是您查询的答案。

我假设由于您描述遍历的方式,您的树是有序的。如果您的树没有排序,您将需要访问每个节点以确定答案,但您可以忽略任何高于树中节点数的值。

虽然上面为 BST 提供了线性解决方案,但您可以更多地利用该结构来获得平均对数解决方案。假设左右节点都是真正的子树,那么算法是:

MinMissingValue(BST t, integer b = 0):
    if (t is empty) return b;
    if (t.root.value - b) > t.root.left.count
        return MinMissingValue(t.root.left, b)
    else
        return MinMissingValue(t.root.right, t.root.value + 1)

该算法依赖于每个子树知道它包含多少个节点的概念。

【讨论】:

  • 您的解决方案适用于二叉搜索树,但不适用于二叉树
  • @songlj:我不否认。提问者提出遍历的方式让我相信这是一棵排序树。
  • 这是一个二叉搜索树。它是排序的;很抱歉造成混乱,我昨晚很累时写了这个。
  • 谢谢哥们,我只需要实现计数。使用 RB-Tree,因此计数会发生变化。
  • 如果它有重复的根,有没有办法做到这一点?
猜你喜欢
  • 2021-12-19
  • 1970-01-01
  • 2012-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多