【问题标题】:Java recursion with BST使用 BST 的 Java 递归
【发布时间】:2020-11-18 08:08:55
【问题描述】:

所以我目前正在编写一个程序,我需要获取一棵充满节点的树,并基本上获取所有节点(每个节点都有一个我需要获取的名称,然后将其放入一个数组中)。我试图通过递归来做到这一点,但我遇到了一些棘手的情况。基本上,我的递归调用完美地完成了树的左侧。但是,当它转到右侧(即树顶部的右侧,即根)时,它将索引设置回 2(而不是继续在左侧停止的位置),我是我对如何解决这个问题有点困惑。这是我的方法和递归方法的代码:

    public Object[] getAllIdentifiers() {
    // TODO Auto-generated method stub
    current = root;
    
    if(root == null)
        return null;
    
    Object[] identifiers = new Object[numberOfIdentifiers];
    getAllIdentifiers(current, identifiers, 0);
    
    return identifiers;
}

private void getAllIdentifiers(Node node, Object[] array, int index) {
    
    if(node != null) {
        array[index] = node.id;
        System.out.println("INDEX: " + index);
    }
    
    if(node.leftChild != null) {
        System.out.println("LEFT");
        index = index + 1;
        getAllIdentifiers(node.leftChild, array, index);
    }
    if(node.rightChild != null) {
        System.out.println("RIGHT");
        index = index + 1;
        getAllIdentifiers(node.rightChild, array, index);
    }
    
}

【问题讨论】:

    标签: java recursion binary-search-tree


    【解决方案1】:

    我的想法是 getAllIdentifiers 中的索引变量没有被全局更新,只是在递归调用中。所以在第一次调用中,index 仍然是 2,因为它只增加了两次。您可以全局更新索引变量,但更优雅的解决方案可能是让 getAllIdentifiers 返回一个 int,以便可以在递归调用中向前传递当前索引(而不是让它无效)。

    【讨论】:

    • 所以如果我使用一个 int,那看起来会是怎样的。我玩弄了这个想法,每次我这样做时,我最终都会添加一个 return 语句来提前停止这些调用。任何帮助将不胜感激。
    • 索引变量不会全局更新,因为变量是按值传递的。而是在调用递归函数时传递 +1。
    • @RajeshPantula 所以这样做时它会做同样的事情,只是它在向右移动时从索引 1 重新开始。
    • @SilentThief,我实际上并没有尝试过,但如果你这样做 index += getAllIdentifiers(..) 并在最后返回 index 就是我的想法。并且在将节点添加到 array[] 时,您还将增加索引。对于全局解决方案,我认为您每次向数组添加节点时只需增加全局变量,并使用它来确定 array[globalIndex] = node.id。这不需要传递索引。我仍然认为此评论中提到的第一个解决方案在风格上更清晰。
    • 检查你的 if 条件,这弄乱了索引的传递方式。只需在方法之上添加一个 if 条件来处理 if(root == null)
    【解决方案2】:

    我认为你应该首先决定你想要对你的树进行什么样的遍历(有序、前序或后序),并在此基础上你可以像这样简化你的树遍历:

    public List<Integer> getAllIdentifiers(Node root) {
             List<Integer> list = new LinkedList<>();
            
             preoder(root, list); // if instead of preorder, you need inorder modify your recursive method to add node first and then go to left or right subtree.
             return list; // covert this to array here if you want.
        }
        
        void inorder(Node root, List<Integer> list){
            if(root == null) return ;
            
            list.add(root.Id);
            inorder(root.left, list);
            inorder(root.right, list);
            
        }
    

    使用列表并追加元素,然后生成数组。这将比跟踪索引更容易。如果您出于性能原因想在单次传递中执行此操作,请将索引作为第三个参数传递给方法,并在传递给左右子树时递增。

    【讨论】:

    • 必须按照上面的方法完成。这是为了一个任务。我可以更改私有方法,但不能更改公共方法,并且必须使用我在其他代码中创建的树。
    猜你喜欢
    • 2014-06-30
    • 1970-01-01
    • 2018-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 1970-01-01
    相关资源
    最近更新 更多