Java 使用全局变量与编写递归算法时传递变量

Java 使用全局变量与编写递归算法时传递变量,java,recursion,Java,Recursion,我有一种方法可以展平二叉搜索树。我有两种方法: •使用变量并传递 import java.util.*; public class BST { private Node root; private class Node { private int val; // associated data private Node left, right; // left and right subtree public Node(int val)

我有一种方法可以展平二叉搜索树。我有两种方法:

•使用变量并传递

import java.util.*;

public class BST {

private Node root;

private class Node {
    private int val;             // associated data
    private Node left, right;  // left and right subtree

    public Node(int val) {
        this.val = val;

    }
}   

public ArrayList<Integer> flattenTree(){

    ArrayList<Integer> list = new ArrayList<>();
    flattenTree(root, list);

    return list;
}

public void flattenTree(Node node, ArrayList<Integer> list)
{

    if (node == null)
        return;

    flattenTree(node.left, list);
    list.add(node.val);
    flattenTree(node.right, list);

}    

public static void main(String[] args) {

    BST bst = new BST();

    bst.add(5);
    bst.add(1);
    bst.add(0);
    bst.add(3);

    System.out.println(bst.flattenTree());

}

}
我是java(高中)的初学者,不知道每种方法的优缺点是什么


我能想到的唯一一种方法是#2不必传递列表,因此代码不那么凌乱。

总体而言,全局变量的缺点是双重的

1) 您只有一个全局变量,因此不能同时运行代码的两个副本(即多个线程)

2) 全局变量可以在代码可能不期望的其他地方修改


您的第一个答案是更好的工程解决方案。

为了补充@caskey的观点,我想指出第一版代码的另外两个主要优点

首先,接受显式列表的代码更难被错误使用。如果调用代码的第二个版本,则需要

  • 确保没有其他人在并行线程中调用该方法
  • 确保列表变量已初始化
  • 确保列表中没有其他内容,并且
  • 记住,当你看完这张单子时,要把它读完
如果您忘记执行这些操作,您的程序将不会按预期运行,但不会出现任何编译器错误。这使得代码更难正确使用,并增加了程序中出现更多错误的可能性

第二,第一个版本更容易描述。代码的第一个版本可以描述为“使用树的顺序遍历填充给定列表”。第二个版本是“在列表的现有内容上附加树的顺序遍历”。第二个版本更难描述第二个版本的功能,因此文档的负担更大。另外,对于程序员来说,第一次阅读代码更难理解它的功能

希望这有帮助

要问的好问题:

  • 该类是否有需要保留的状态
  • 如果是,状态是什么(即字段)
  • 您可以通过在方法调用中传递参数来避免状态,这样可以更容易地测试代码

嘿,谢谢你的回答。从我所读到的,似乎“全局变量”是一个特定于类或“静态”的变量。在我的例子中,它不是一个静态变量,它是否仍然属于全局变量?静态变量可以被视为全局变量,因为无论类被实例化多少次,该变量只存在一个实例。类变量在类的每个实例中都有一个不同的变量。无论如何,将列表传递给函数比这两种方法都更正确,因为在一个函数中仍然可以有两个调用者。
import java.util.*;

public class BST {

private Node root;

ArrayList<Integer> list = new ArrayList<>();    

private class Node {
    private int val;             // associated data
    private Node left, right;  // left and right subtree

    public Node(int val) {
        this.val = val;

    }
}   

public ArrayList<Integer> flattenTree(){

    flattenTree(root);

    return list;
}

public void flattenTree(Node node)
{

    if (node == null)
        return;

    flattenTree(node.left);
    list.add(node.val);
    flattenTree(node.right);

}    

public static void main(String[] args) {

    BST bst = new BST();

    bst.add(5);
    bst.add(3);
    bst.add(1);
    bst.add(0);
    bst.add(3);
    bst.add(3);

    bst.printInorder();
    System.out.println(bst.flattenTree());

}
sgupta$ java BST
[0, 1, 3, 5]