繁体   English   中英

为什么我们需要二进制搜索树中的父节点-C#

[英]Why do we need Parent Node in Binary Search Tree - C#

我才刚刚开始学习数据结构,所以请忍受我的愚蠢,我正在尝试开发自己的BST版本,我不明白为什么需要父Node? 这项工作不应该很好吗。

class BST 
{
    private Node root;

    public BST()
    {
        root = null;
    }

    public void insert(int value) 
    {
        Node temp = new Node();
        temp.value = value;

        if (root == null)
        {
            root = temp;
            return;
        }

        Node current = root;

        while (current != null) 
        {
            if (value <= current.value)
            {
                current = current.lc;
            }
            else 
            {
                current = current.rc;
            }
        }

        current = temp;
    }
}

class Node
{
    public Node lc;
    public int value;
    public Node rc;
}

我肯定缺少某些东西,我无法理解或了解它的含义,当current为null时,我们已经在需要插入节点的位置,为什么需要父节点。

您正在将“ null”设置为某个实例。

在while循环中,电流最终变为空,并且您丢失了节点之间的连接。

要解决此问题,您应该保留树的最后一个节点。

您可以尝试以下方法:

class BST
{
    private Node root;

    public BST()
    {
        root = null;
    }

    public void insert(int value)
    {
        root = insert(root, value);
    }

    private Node insert(Node node, int value) {
        // if the given node is null it should be new node
        if (node == null) {
            node = new Node();
            node.value = value;
            return node;
        }

        if (value < node.value)
            // if our value lower then current value then we will insert left node recursively
            node.lc = insert(node.lc, value);
        else if (value > node.value)
            // if our value higher then current value then we will insert right node recursively
            node.rc = insert(node.rc, value);

        return node;
    }

    public void print() {
        print(root);
    }

    private void print(Node node) {
        if (node != null) {
            print(node.lc);
            Console.WriteLine(node.value);
            print(node.rc);
        }
        return;
    }
}


public static void main(String[] args) {

    BST bst = new BST();

    bst.insert(5);
    bst.insert(25);
    bst.insert(15);
    bst.insert(4);

    bst.print();
}

输出为:

4
5
15
25

这可能有效

class BST
{
    private Node root = null;

    public void insert(int value)
    {
        Node temp = new Node { value = value };

        if (root == null)
        {
            root = temp;
            return;
        }

        var current = root;

        while (current != null)
        {
            if (value <= current.value)
            {
                if (current.lc == null)
                {
                    current.lc = temp; 
                    break;
                }
                current = current.lc;
            }
            else
            {
                if (current.rc == null)
                {
                    current.rc = temp; 
                    break;
                }
                current = current.rc;
            }
        }

    }
}

class Node
{
    public Node lc;
    public int value;
    public Node rc;
}

您正在混合变量和对字段/变量的引用。 current变量保存lcrc字段的 (该字段的副本)。 设置变量不会设置相应的字段,只会为变量分配另一个值。

因此线

current = temp;

不会在BST中插入节点。

C#7.0引入的ref局部变量和return以及C#7.3引入的改进允许重新分配ref局部变量,这是您尝试做的事情。

ref局部变量正是您的意图-它们包含其他某些字段/变量的位置(引用,地址)。 因此,以下工作(需要C#7.3!):

public void insert(int value)
{
    ref Node nodeRef = ref root;
    while (nodeRef != null)
    {
        if (value <= nodeRef.value)
            nodeRef = ref nodeRef.lc;
        else
            nodeRef = ref nodeRef.rc;
    }
    nodeRef = new Node { value = value };
}

请注意ref关键字的用法。 您可以使用nodeRef = ref …来分配变量的引用(地址)(在本例中为root或某个节点的lcrc字段),并使用nodeRef = …来给nodeRef指向的变量分配值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM