范围查询 - 树不包含上限和/或下限

时间:2016-05-05 16:54:26

标签: algorithm range binary-search-tree

假设我有Binary Search Tree

        50
     /       \
    17        72
  /    \     /   \
 12    23   54   76
 /\    /     \
9 14  19     67

抱歉,我吮吸树木

我想返回属于特定范围的所有节点。例如

[12, 23] --> {12, 14, 17, 23, 19}

我的方法很简单

  1. 查找LCA
  2. 查找下限
  3. while node!= LCA.parent,添加右子树
  4. 从LCA,节点!=上限,添加左子树
  5. 添加上限
  6. 的上限和左子树

    但是,如果树中没有包含一个或两个边界,该怎么办?例如

    [11, 72] --> {12, 14, 17, 23, 19, 50, 54, 67, 72}
    

    我的方法看起来很相似,除了搜索边界,搜索直到你的边界被节点子节点超过。因此,在找到“LCA”(不是真正的LCA,因为它不存在)之后,找到11.到达12后,看到左边的孩子少于11,所以停在那里。

    1. 是否有更有效的解决方案来执行此范围查询? BST不是强制性的,它看起来像是一个很好的数据结构。
    2. 我的方法是否有效/当树中没有包含边界时是否有效?

2 个答案:

答案 0 :(得分:2)

正如@Nico建议的那样,你只需要一个递归算法来遍历树,你不需要关心LCA。二叉树是二叉树搜索树的事实允许您执行一些优化并避免遍历整个树。例如:如果节点的值低于下限,则不要遍历节点的左分支。

void FindNodesInBound(BSTNode node, int lowerBound, int upperBound, List<int> matches) {
    if (node != null) {
        if (node.Value >= lowerBound)
            FindNodesInBound(node.Left, lowerBound, upperBound, matches);
        if (node.Value >= lowerBound && node.Value <= upperBound)
            matches.Add(node.Value);
        if (node.Value <= upperBound)
            FindNodesInBound(node.Right, lowerBound, upperBound, matches);
    }
}

答案 1 :(得分:1)

一种可能性:

  • &#34;发现&#34;较低的值(例如12)。它返回一个允许inorder walk的数据结构,例如C ++中的std::map::iterator。简单来说,它是从根到搜索节点的路径。
  • 从找到的节点开始inorder walk,直到达到更高的值(示例中为23)。

因为问题是,&#34; BST不是强制性的,它看起来像是一个很好的数据结构。&#34;,另一种选择是将数字保存在一个排序的数组中。这当然限制了修改数字集的选项。在排序数组中,二进制搜索较低的数字并开始向更高端行走(与BST方法相同。)