Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
(java)DFS遍历中的奇怪列表值_Java_Arraylist_Tree_Traversal_Microsoft Distributed File System - Fatal编程技术网

(java)DFS遍历中的奇怪列表值

(java)DFS遍历中的奇怪列表值,java,arraylist,tree,traversal,microsoft-distributed-file-system,Java,Arraylist,Tree,Traversal,Microsoft Distributed File System,我试图解决一个问题: 打印二叉树从根到叶的所有路径 我编写了以下代码,结果是正确的: public void printPath(TreeNode root) { printDFS(root, new int[1000], 0); } private void printDFS(TreeNode r, int[] path, int idx){ if (r == null) return; path[idx] = r.val; idx++;

我试图解决一个问题:

打印二叉树从根到叶的所有路径

我编写了以下代码,结果是正确的:

public void printPath(TreeNode root) {

    printDFS(root, new int[1000], 0);

}



private void printDFS(TreeNode r, int[] path, int idx){
    if (r == null) return;

    path[idx] = r.val;
    idx++;

    /* if it's leaf, print path: from root to leaf */
    if (r.left == null && r.right == null) 
        printOnePath(path, idx);

    else {
        /* go left, go right */
        printDFS(r.left,  path, idx);
        printDFS(r.right, path, idx);
    }
}


private void printOnePath(int[] path, int idx) {
    for (int i = 0; i < idx; i++) {
        System.out.print(path[i] + " ");
    }
    System.out.println();         
}
public void打印路径(TreeNode root){
printDFS(根,新整数[1000],0);
}
私有void printDFS(TreeNode r,int[]路径,int idx){
如果(r==null)返回;
路径[idx]=r.val;
idx++;
/*如果是叶,打印路径:从根到叶*/
if(r.left==null&&r.right==null)
printOnePath(path,idx);
否则{
/*向左走,向右走*/
printDFS(右左,路径,idx);
printDFS(右,路径,idx);
}
}
私有void printOnePath(int[]路径,int idx){
对于(int i=0;i
然而,
当我尝试使用ArrayList来存储路径数据而不是 int[]
这种方法是错误的
输出结果真的让我不知所措

public void打印路径(TreeNode root){
printDFS(root,newarraylist(),0);
}
私有void printDFS(TreeNode r,列表路径,int idx){
如果(r==null)返回;
路径添加(r.val);
idx++;
/*如果是叶,打印路径:从根到叶*/
if(r.left==null&&r.right==null)
printOnePath(path,idx);
否则{
/*否则,向左走,向右走*/
printDFS(右左,路径,idx);
printDFS(右,路径,idx);
}
}
私有void printOnePath(列表路径,int-idx){
对于(int i=0;i
例如:

对于二叉树:

第一个标准是:(正确)

10 5 3 3 
10 5 3 -2 
10 5 2 1 
10 -3 11

第二个标准是:(错)

10 5 3 3 
10 5 3 3 
10 5 3 3 
10 5 3

我相信初始ArrayList在每个DFS开始时都已设置为空。 为什么即使使用相同的方法,int数组的结果也完全不同

有人知道为什么吗?非常感谢

行:

path[idx] = r.val;

它们并不等同

结果是,第一个路径之后的后续路径将添加到列表的末尾。当您打印
路径
时,不会看到这些,因为您只打印到
idx
元素

我不相信Java中有数组赋值的直接列表等价物

召唤

path.set(idx, r.val);
不起作用,因为Java不会自动增加列表

召唤

path.add(idx, r.val);
由于它将现有元素向右移动,因此也不起作用


如果您想使用列表,我想您必须在打印后将其清除。

区别在于
idx
,一个
int
,是按值传递的。但是,
ArrayList
路径
是一个对象;因此,虽然作为引用的参数是按值传递的,但是
path
引用的对象不是按值传递的,而是在递归方法的所有调用中共享的

这意味着在第一个方法中,当您递归调用它时:

    printDFS(r.left,  path, idx);
    printDFS(r.right, path, idx);
r.left
上调用
printDFS
时,假设
idx
为3。当递归方法使用
idx++
递增
idx
时,它们正在递增
idx
的新副本。因此,当递归方法最终结束并返回时,该方法使用的
idx
的副本仍然是3,因此它将调用
printDFS(r.right,path,3)
。这会产生不同,因为您使用
idx
设置
path[idx]

在第二种方法中,
idx
的行为方式相同,但在构建
ArrayList
时没有使用它。相反,您将添加到
ArrayList
。所以当你打电话的时候

    printDFS(r.left,  path, idx);
    printDFS(r.right, path, idx);
现在,如果在
r.left
上调用
printDFS
path
有3个元素,当递归调用结束并返回时,它们已添加到
ArrayList
——并且由于此对象在所有递归调用中共享,
path
仍将包含递归调用添加到其中的所有元素。因此,与第一个代码示例不同,您调用的
printDFS(r.right…
值与调用的
printDFS(r.left…
值不同

有几种方法可以解决此问题:

  • 使用
    idx
    设置数组元素,如另一个答案所示。但是,您需要检查
    idx
    是否是现有元素的索引,如果元素存在,则使用
    set
    ;如果
    idx
    等于
    path.size(),则使用
    add

  • 在调用每个
    printDFS
    之前,复制一份
    path
    。这确保了所有递归调用都有自己的数组干净副本。(或在
    printDFS
    的开头复制一份,并使用该副本而不是原始路径;这应确保没有
    printDFS
    修改其调用者的
    路径

  • 确保每个
    printDFS
    都保留它找到路径的方式。因此,由于
    printDFS
    在数组末尾添加了一个新元素,因此请在返回之前删除数组的最后一个元素。(我相信这会奏效,尽管我还没有测试过它。但是,我一般不推荐这种方法;对于更复杂的递归情况,正确地进行“清理”可能非常困难。)


  • 我遵循ajb提到的复制策略(本评论中的选项2)。这是修改后的代码

        import apple.laf.JRSUIUtils;
    
        import java.util.ArrayList;
        import java.util.List;
    
        /**
         * Created by anilwaddi on 8/1/17.
         */
        public class DFSTest {
    
    
          public static void main(String args[]) throws Exception {
    
            DFSTest test = new DFSTest();
            test.printDFS();
        /*
        10 5 3 3
        10 5 3 -2
        10 5 2 1
        10 -3 11
         */
          }
    
          TreeNode root;
    
          DFSTest() {
            TreeNode node41 = new TreeNode(3, null, null);
            TreeNode node42 = new TreeNode(-2, null, null);
            TreeNode node43 = new TreeNode(1, null, null);
    
    
            TreeNode node31 = new TreeNode(3, node41, node42);
            TreeNode node32 = new TreeNode(2, node43, null);
            TreeNode node33 = new TreeNode(11, null, null);
    
            TreeNode node21 = new TreeNode(5, node31, node32);
            TreeNode node22 = new TreeNode(-3, node33, null);
            root = new TreeNode(10, node21, node22);
          }
    
          public void printDFS() {
            printPath(root);
          }
    
          public void printPath(TreeNode root) {
            printDFS(root, new ArrayList<Integer>());
    
          }
    
          private void printDFS(TreeNode r, List<Integer> path ) {
            if (r == null) return;
    
            path.add(r.val);
    
            /* if it's leaf, print path: from root to leaf */
            if (r.left == null && r.right == null)
              printOnePath(path );
    
            else {
                /* otherwise: go left, go right */
              List<Integer> newPathLeft = new ArrayList<>();
              newPathLeft.addAll(path);
              printDFS(r.left, newPathLeft);
    
              List<Integer> newPathRight = new ArrayList<>();
              newPathRight.addAll(path);
              printDFS(r.right, newPathRight);
            }
          }
    
    
          private void printOnePath(List<Integer> path ) {
            for (int i = 0; i < path.size(); i++) {
              System.out.print(path.get(i) + " ");
            }
            System.out.println();
          }
    
          private class TreeNode {
            TreeNode left;
            TreeNode right;
            Integer val;
    
            TreeNode(Integer val) {
              this.val = val;
            }
    
            TreeNode(Integer val, TreeNode left, TreeNode right) {
              this.val = val;
              this.left = left;
              this.right = right;
            }
          }
        }
    
    导入apple.laf.jrsuitils;
    导入java.util.ArrayList;
    导入java.util.List;
    /**
    *anilwaddi于2017年8月1日创建。
    */
    公共类测试{
    公共静态真空总管(
    
        printDFS(r.left,  path, idx);
        printDFS(r.right, path, idx);
    
        import apple.laf.JRSUIUtils;
    
        import java.util.ArrayList;
        import java.util.List;
    
        /**
         * Created by anilwaddi on 8/1/17.
         */
        public class DFSTest {
    
    
          public static void main(String args[]) throws Exception {
    
            DFSTest test = new DFSTest();
            test.printDFS();
        /*
        10 5 3 3
        10 5 3 -2
        10 5 2 1
        10 -3 11
         */
          }
    
          TreeNode root;
    
          DFSTest() {
            TreeNode node41 = new TreeNode(3, null, null);
            TreeNode node42 = new TreeNode(-2, null, null);
            TreeNode node43 = new TreeNode(1, null, null);
    
    
            TreeNode node31 = new TreeNode(3, node41, node42);
            TreeNode node32 = new TreeNode(2, node43, null);
            TreeNode node33 = new TreeNode(11, null, null);
    
            TreeNode node21 = new TreeNode(5, node31, node32);
            TreeNode node22 = new TreeNode(-3, node33, null);
            root = new TreeNode(10, node21, node22);
          }
    
          public void printDFS() {
            printPath(root);
          }
    
          public void printPath(TreeNode root) {
            printDFS(root, new ArrayList<Integer>());
    
          }
    
          private void printDFS(TreeNode r, List<Integer> path ) {
            if (r == null) return;
    
            path.add(r.val);
    
            /* if it's leaf, print path: from root to leaf */
            if (r.left == null && r.right == null)
              printOnePath(path );
    
            else {
                /* otherwise: go left, go right */
              List<Integer> newPathLeft = new ArrayList<>();
              newPathLeft.addAll(path);
              printDFS(r.left, newPathLeft);
    
              List<Integer> newPathRight = new ArrayList<>();
              newPathRight.addAll(path);
              printDFS(r.right, newPathRight);
            }
          }
    
    
          private void printOnePath(List<Integer> path ) {
            for (int i = 0; i < path.size(); i++) {
              System.out.print(path.get(i) + " ");
            }
            System.out.println();
          }
    
          private class TreeNode {
            TreeNode left;
            TreeNode right;
            Integer val;
    
            TreeNode(Integer val) {
              this.val = val;
            }
    
            TreeNode(Integer val, TreeNode left, TreeNode right) {
              this.val = val;
              this.left = left;
              this.right = right;
            }
          }
        }