【问题标题】:Please explain the given binary tree code that is in java请解释java中给定的二叉树代码
【发布时间】:2015-10-10 20:57:30
【问题描述】:

我找不到人来正确地解释这个 java 代码,所以最后我发布了这个问题。请解释该特定语句如何影响树的过程。问题在 cmets 中说明。我在 BST 中有问题类。

 import java.util.Scanner;

 class BSTNode
 {
     BSTNode left, right;
     int data;

     public BSTNode()
     {
         left = null;
         right = null;
         data = 0;
     }

     public BSTNode(int n)
     {
         left = null;
         right = null;
         data = n;
     }

     public void setLeft(BSTNode n)
     {
         left = n;
     }

     public void setRight(BSTNode n)
     {
         right = n;
     }

     public BSTNode getLeft()
     {
         return left;
     }

     public BSTNode getRight()
     {
         return right;
     }

     public void setData(int d)
     {
         data = d;
     }

     public int getData()
     {
         return data;
     }     
 }

 class BST
 {
     private BSTNode root;

     public BST()
     {
         root = null;
     }

     public boolean isEmpty()
     {
         return root == null;
     }

为什么插入函数写成root=insert(.....。每次都返回 root = 实际的根元素吗?

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

我了解插入过程是如何进行的,但是插入函数返回的是什么?我知道它返回了一些节点,但是在迭代过程中这个过程是如何进行的?

     private BSTNode insert(BSTNode node, int data)
     {
         if (node == null)
             node = new BSTNode(data);
         else
         {
             if (data <= node.getData())
                 node.left = insert(node.left, data);
             else
                 node.right = insert(node.right, data);
         }

         return node;
     }

     public void delete(int k)
     {
         if (isEmpty())
             System.out.println("Tree Empty");
         else if (search(k) == false)
             System.out.println("Sorry "+ k +" is not present");
         else
         {
             root = delete(root, k);

再次,为什么删除函数写成root=delete(.....?每次都返回 root =actual root 元素吗?

             System.out.println(k+ " deleted from the tree");
         }
     }

     private BSTNode delete(BSTNode root, int k)
     {
         BSTNode p, p2, n;

         if (root.getData() == k)
         {
             BSTNode lt, rt;
             lt = root.getLeft();
             rt = root.getRight();

             if (lt == null && rt == null)
                 return null;
             else if (lt == null)
             {
                 p = rt;
                 return p;
             }
             else if (rt == null)
             {
                 p = lt;
                 return p;
             }
             else
             {
                 //case when we delete node having both children.
                 p2 = rt;
                 p = rt;

                 //getting the min of the right child subtree in p variable .
                 while (p.getLeft() != null)
                     p = p.getLeft();

                 p.setLeft(lt);

请解释这里发生了什么以及为什么返回 p2 即 rt。

                 return p2;
             }
         }

         if (k < root.getData())
         {
             n = delete(root.getLeft(), k);
             root.setLeft(n);
         }
         else
         {
             n = delete(root.getRight(), k);
             root.setRight(n);             
         }

         return root;
     }

     public int countNodes()
     {
         return countNodes(root);
     }

【问题讨论】:

  • 请清理您的问题。
  • 感谢编辑。我是新手。

标签: java recursion recursive-datastructures


【解决方案1】:

在代码的删除部分,您所做的是检查节点(称为根)的数据值是否等于您要删除的值 (k)。如果这是真的,那么你检查你似乎掌握的两个孩子。因此,当您的节点的两个子节点都不是null 时,我们开始回答您的问题。在这种情况下,您想删除您所在子树的当前节点(根),但是您需要选择一个节点(左或右)来提升到该节点的位置。因此(假设这棵树不平衡)您只需选择(左或右)子树以提升到已知根。请记住,您只是调用当前节点根,因为它是较大树中某个子树的根(这并不意味着树的实际根,除非那是作为根传入的值)。知道右子树中的所有值都将大于左子树中的值,您只需获取当前节点的左子树,然后尽可能向下递归右子树的左子树,直到您'到最后。然后将此节点的左子节点设置为整个左子树。

//case when we delete node having both children.
p2 = rt;
p = rt;

//getting the min of the right child subtree in p variable .
while (p.getLeft() != null)
p = p.getLeft();

p.setLeft(lt);

声明中的注意事项

p = rt;

您将 P 设置为右子树的根。那么p现在就是传入的当前根的右孩子了。

while (p.getLeft() != null)
    p = p.getLeft();

p.setLeft(lt);

这基本上是说对于那个右子树,如果根节点有一个左子节点,则将p 设置为该值并继续这样做直到该值为空。这将继续沿该右子树的左子树向下移动。最后,一旦该值为空

p.setLeft(lt);

将右子树中最左边的叶子的左子节点设置为您开始使用的整个左子树。并返回您所说的节点是原始的右子树(现在原始的左子树附加到其最左边的叶子)。

【讨论】:

  • 因此,您想删除 12,但您注意到 12 有左右两个孩子,因此您将它们分别保存为 ltrt,然后将 p 设置为右边这是 21。现在虽然 21 有一个左孩子,但您将 p 设置为该孩子,所以现在 19 但现在 19 的左孩子为空,所以您将其左孩子设置为 9,您将返回 21,您将其保存为 @ 987654333@ 这将被设置为 5 的右孩子。所以,现在 12 消失了,而 21 在它的位置,9 已经向下移动成为 19 的左孩子。
  • 我认为它与您所说的完全一样,但本网站解释删除节点否则。如果本网站解释属实,则该程序的删除过程是错误的。请检查此link并验证如果这是删除节点的正确方法。
  • 您提供的链接也是正确的,实际上稍微好一些,因为它使树的深度尽可能低。解释它的方式是您的代码执行它的方式,但是您的链接描述它的方式也是正确的(并且更好)。你只需要慢慢地单步调试代码,看看它在做什么。
猜你喜欢
  • 2015-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-28
  • 1970-01-01
  • 2014-08-12
  • 1970-01-01
  • 2016-02-20
相关资源
最近更新 更多