【问题标题】:binary search tree find if value exists二叉搜索树查找值是否存在
【发布时间】:2017-09-24 02:20:29
【问题描述】:

正在尝试学习树节点...

    Binary search tree (BST) is a binary tree where the value of each node is larger or equal to the values in all the nodes in that node's left subtree and is smaller than the values in all the nodes in that node's right subtree.

Write a function that checks if a given binary search tree contains a given value.

For example, for the following tree:

n1 (Value: 1, Left: null, Right: null)
n2 (Value: 2, Left: n1, Right: n3)
n3 (Value: 3, Left: null, Right: null)
Call to Contains(n2, 3) should return true since a tree with root at n2 contains number 3.

到目前为止,我得到了...

 public class BinarySearchTree
    {
        public static bool Contains(Node root, int value)
        {
            foreach (var v in root)
            {
                if (root.Value == value)
                {
                    //value found return true
                }
            }
        }

        public static void Main(string[] args)
        {
            Node n1 = new Node(1, null, null);
            Node n3 = new Node(3, null, null);
            Node n2 = new Node(2, n1, n3);

            Console.WriteLine(Contains(n2, 3));
        }
    }

但 root 标记为不可用,如果我做 root。我得到了字符串、值、左、右的选项。

我不能像列表一样遍历节点吗? 如何检查是否在根目录中找到值? 谢谢


更新 啊,是的,好的...感谢 juharr 的回复,所以我已将代码更新为...

public static bool Contains(Node root, int value)
            {
                    if (root.Value == value)
                    {
                        return true;
                    }
                    else if (root.Value > value)
                    {
                        if (root.Right == null)
                        {
                            Contains(root.Left, value);
                        }
                        Contains(root.Right, value);
                    }
                    else //(root.Value < value)
                    {
                        if (root.Left == null)
                        {
                            Contains(root.Right, value);
                        }

                        Contains(root.Left, value);
                    }

                return false;
            }

但是在第二个循环中,round root 为 null 并导致崩溃?

【问题讨论】:

  • 你基本上需要检查值是否匹配,如果不匹配,则确定它是更大还是更小,并分别递归调用左侧或右侧节点上的方法。
  • 感谢您的回复我试过了,请查看 OP 更新
  • 如果root == null怎么办?
  • 如果左侧或右侧是null,则该值不存在,您无需检查另一个值。而是预先检查null
  • 当我再次调用 contains() 时,它只传递叶子而不是导致 null 的整个节点

标签: c# nodes


【解决方案1】:

你已经接近了,但这就是你真正想要的

public static bool Contains(Node root, int value)
{
    if (root == null) return false;
    if (root.Value == value) return true;
    if (root.Value > value) return Contains(root.Left, value);
    return Contains(root.Right, value);
}

所以如果rootnull 那么没有数字所以你返回false。然后检查该值是否匹配,如果匹配则返回 true。然后如果root 的值更大,则返回左子树上递归调用的结果。最后,您只需在右子树上返回递归调用的结果,因为此时您知道根值较小。

这是一种非递归的搜索方式

public static bool Contains(Node root, int value)
{
    while(root != null)
    {
        if(root.Value == value) return true;
        if(root.Value > value) root = root.Left;
        else root = root.Right;
    }

    return false;
}

在这里,我们循环直到遇到null 节点,然后根据比较简单地将root 设置为LeftRight,或者如果Value 匹配,则立即返回true。如果我们让它退出循环,则找不到该值。

【讨论】:

    【解决方案2】:

    我不能像遍历列表那样遍历节点吗?

    可以遍历 BST - 使用堆栈传递子节点会有所帮助(如 here 所示)。因此,您可以将 root 的子代放入堆栈中,然后将它们的值与您的目标 value 进行比较。

    话虽如此,可以说更直观的方法是递归的——理论上你会检查当前节点的值,然后递归调用Contains——将当前节点的rightleft子传递给它直到找到目标Value,否则不要。

    在任何一种方法中,您都需要利用您在问题中指出的 BST 的优势:

    二叉搜索树 (BST) 是一种二叉树,其中每个节点的值大于或等于该节点左子树中所有节点的值且小于该节点右子树中所有节点的值.

    考虑到这一点,您将能够在 O(log n) 时间通过“切断”您知道不需要检查的值来实现它(由于当前节点的值与您的目标 value 相关) .

    【讨论】:

    • 感谢您的回复...我想我已经尝试过您在更新 OP 时提出的建议,但是当我再次调用 contains() 时,它只会传入叶子而不是整个节点,这会导致空
    • 这是您在链接上发布的 java 答案
    • 是的,只是一个概念参考。很高兴看到你成功了。
    猜你喜欢
    • 2012-06-05
    • 1970-01-01
    • 2018-05-16
    • 1970-01-01
    • 1970-01-01
    • 2017-09-28
    • 1970-01-01
    • 1970-01-01
    • 2019-04-09
    相关资源
    最近更新 更多