【问题标题】:Why do we need Parent Node in Binary Search Tree - C#为什么我们需要二叉搜索树中的父节点 - C#
【发布时间】:2019-01-19 13:08:48
【问题描述】:

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

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 为空时,我们已经到了我们需要插入节点的位置,为什么我们需要一个父节点。

【问题讨论】:

  • “需要”是什么意思?
  • 我无法正确理解您所缺少的是什么。能不能说的详细点?
  • Umm V0ldek,我不明白你...据我所知,我们需要一个节点来指向我们要插入的节点的父节点。
  • 我为创建 BST 编写的上述代码对插入函数有效吗?
  • 不,不是。 current = temp; 没有任何用处,只是分配局部变量。为了进行实际插入,必须将temp 分配给parent.lcparent.rc

标签: c# data-structures tree binary-search-tree


【解决方案1】:

您正在为某个实例设置“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

【讨论】:

    【解决方案2】:

    您将变量与对字段/变量的引用混合在一起。 current 变量保存lcrc 字段(字段的副本)的。设置变量并没有设置对应的字段,只是给变量赋值另一个值。

    因此这条线

    current = temp;
    

    不在 BST 中插入节点。

    C#7.0 引入 ref locals and returns 和 C#7.3 引入 improvements 允许重新分配 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.

    【讨论】:

      【解决方案3】:

      这可能有效

      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;
      }
      

      【讨论】:

        猜你喜欢
        • 2015-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-12
        • 1970-01-01
        相关资源
        最近更新 更多