【问题标题】:Binary Search Tree toString二叉搜索树 toString
【发布时间】:2016-08-22 09:16:57
【问题描述】:

我无法以教授想要的格式打印出二叉搜索树。

他的格式是这样的:

{(12,10,13),(10,8,11),(8,6,9),(6,4,7),(4,2,5),(2,1,3),(1,*,*),(3,*,*),(5,*,*),(7,*,*),(9,*,*),(11,*,*),(13,*,*)} 

子集中的第一个数字是根节点,左右节点是左右子节点。循环迭代后,左子节点将成为根节点。一切正常,直到我到达子集中仅存在一个节点的位置。它只是打印 (1, *, *) 直到最后,我不知道如何以另一种方式做到这一点。这个 toString 方法可以递归做吗?

我的代码:

public String toString()
{
   if (root == null)
       return "{}";
   String str = "{";
   Node tmp = root;
   for (int i = 0; i < size; i++)
   {   
        if (tmp.right != null && tmp.left == null)
            str += "("+tmp.data+", "+tmp.right.data+", *)";
        if (tmp.left != null && tmp.right == null)
            str += "("+tmp.data+", "+tmp.left.data+", *)";
        if (tmp.left == null && tmp.right == null)          
            str += "("+tmp.data+", *, *)";
        else
            str += "("+tmp.data+", "+tmp.left.data+", "+tmp.right.data+")";

        if (tmp.left != null)
            tmp = tmp.left;
   }

   return str += "}";   
}

【问题讨论】:

  • 如果格式为(root,left,right),则应在第一个if语句中翻转*tmp.right.data

标签: java recursion binary-search-tree


【解决方案1】:

终于弄明白了,谢谢大家帮忙。这是我最后写的递归打印二叉搜索树

   public String toString()
   {   
       if (root == null)
           return "{}";   
       return "{"+toString(root) + "}";

   }
   private String toString(Node parent)
   {
       if (parent.left == null && parent.right == null)
           return "(" + parent.data + ", *, *)";
       else if (parent.left == null && parent.right != null)
           return "(" + parent.data + ", *,"+parent.right.data+" )" + toString(parent.right);
       else if (parent.left !=null && parent.right == null)
           return"(" + parent.data + ", "+parent.left.data+", *)"+ toString(parent.left);
       else
           return "(" + parent.data + ", "+parent.left.data+", "+parent.right.data+")" + toString(parent.left) + toString(parent.right);          

   }  

【讨论】:

    【解决方案2】:

    这种方法取决于您如何设置对象,但我通常有一个 Node 类来执行递归操作。如果以这种方式实现,您应该会看到像这样的输出

    {(12,10,13),(10,8,11),(8,*,*),(11,*,*),(13,*,*)}
    

    对于这个例子,我们将有一个方法在Node 类上返回您的(data,left,right) 格式。

    public class Node<T>
    
        protected T data;
        protected Node<T> left;
        protected Node<T> right;
    
        public String tuple() {
            StringBuilder sb = new StringBuilder("(")
                    .append(this.data)
                    .append(",");
            sb.append(this.left == null ? "*" : this.left.data)
                    .append(",");
            sb.append(this.right == null ? "*" : this.right.data)
                    .append(")");
            return sb.toString();
        }
    
        // other methods
    }
    

    然后,递归字符串将像这样在toString中实现。

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            String divider = ",";
    
            sb.append(this.tuple()).append(divider);
    
            if (this.left != null) {
                sb.append(this.left).append(divider); // recurse left
            }
    
            if (this.right != null) {
                sb.append(this.right).append(divider); // recurse right
            }
    
            if (sb.length() > divider.length() - 1) {
                sb.setLength(sb.length() - divider.length());
            }
    
            return sb.toString();
        }
    }
    

    然后,在某些BinaryTree 类中,您可以拥有

    public class BinaryTree<E extends Comparable<? super E>> {
    
        protected Node<E> root;
    
        @Override
        public String toString() {
            return "{"
                    + (root == null ? "" : String.valueOf(this.root)) +
                    "}";
        }
    
        // other methods
    
    }
    

    【讨论】:

    • 我尝试了你的方法,但我不知道出了什么问题。对于第一个元组,它会按原样打印 (12, 10, 13)。对于其余的,它只是打印出它们的内存位置。
    • 另外,这到底是什么递归呢,你在哪里调用了 toString() 呢?
    • sb.append(this.right) 会调用this.right.toString(),就像System.out.println(this.right) 会做的那样。
    • 旁注,它实际上是一个哈希码,而不是内存位置。但这很奇怪。 leftright 都是 Node 实例吗?
    • 既然你用它来做出接受的答案,你可能会投票赞成这个答案。
    【解决方案3】:

    听起来你想要toString(几乎)生成以下内容:

    1. 一个{
    2. 根节点的三元组
    3. 逗号和toString 表示左侧节点(如果它不为空)
    4. 逗号和toString 表示正确的节点,如果它不为空
    5. 一个}

    唯一的问题是递归调用应该打印括号;我会把它留作练习。

    【讨论】:

      【解决方案4】:

      对于初学者,我认为您希望将所有四个子句都放在 if-then-else 结构中。目前,前两种情况(一个孩子)也会执行“else”子句。

      主要问题是你永远不会回来使用右子树:唯一的移动逻辑是向左。您的循环对树的每个元素执行一次,但您唯一的遍历是在左侧。您需要六个步骤才能到达节点 1,但您永远不会回溯到任何正确的子节点。

      我怀疑你会想用递归例程来处理这个问题,一个为左分支和右分支调用自身的例程。

      这能让你继续前进吗?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        • 1970-01-01
        • 1970-01-01
        • 2010-10-26
        相关资源
        最近更新 更多