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

时间:2015-01-17 02:23:55

标签: 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) {
        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());

}

}

•使用类变量:

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]

我是java(高中)的初学者,并想知道每种方法的优点和缺点是什么。

我能想到的唯一一个问题就是方法#2的代码不那么混乱,因为不必通过列表。

3 个答案:

答案 0 :(得分:3)

要添加到@ caskey的观点,我想指出第一版代码的另外两个主要优点。

首先,接受显式列表的代码难以正确使用。如果您调用代码的第二个版本,则需要

  • 确保没有其他人在并行线程中调用该方法,
  • 确保列表变量已初始化,
  • 确保该列表尚未包含任何其他内容,
  • 记得在你完成它之后阅读清单。

如果您忘记执行其中任何操作,您的程序将无法按预期运行,但您不会收到任何编译器错误,表明这一点。这使得代码更难以正确使用,并增加了您在程序中获得更多错误的机会。

其次,第一个版本有一个更简单的描述。代码的第一个版本可以描述为&#34;使用树的顺序遍历来填充给定列表。&#34;第二个版本是&#34;附加到列表list的现有内容以及树的顺序遍历。&#34;描述第二个人所做的事情变得更加困难,因此文档的负担更大。此外,程序员第一次阅读代码时更难理解它的作用。

希望这有帮助!

答案 1 :(得分:2)

一般来说,全局变量的缺点是双重的。

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

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

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

答案 2 :(得分:0)

要问的好问题:

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