java - BST 层级顺序遍历 list.clear() and list = new ArrayList

标签 java memory-management arraylist binary-search-tree tree-traversal

上下文:由于我是 Java 新手,所以我用 Java 创建了一个 BinarySearchTree 类作为学习练习。我目前正在编写一种用于级别顺序遍历(BFS)的方法,该方法返回每个级别的节点值列表的列表,其中顶级列表索引表示级别编号,每个索引处的较低级别列表包含该级别的节点值,例如对于这棵树

       F
      / \
     /   \
    /     \
   B       G
  / \       \
 /   \       \
A     D       I
     / \     /
    C   E   H

levelOrder() 方法将返回

[[F], [B, G], [A, D, I], [C, E, H]]

问题:在实现中,我声明了一个名为“listOfLevels”的顶级列表来保存级别列表,以及一个名为“level”的较低级别列表来存储每个级别的节点(我打算清除并跨级别重用)。但是,我注意到,如果我在将“level”添加到“listOfLevels”后调用“level”上的 List.clear() 方法,我会在“listOfLevels”内获得空列表以获取该方法的返回值,如下所示

[[], [], [], []]

我不知道为什么会发生这种情况。根据 ArrayList 文档,“当将元素添加到 ArrayList 时,其容量会自动增长”,因此我认为在使用 clear() 方法清除上一级的值后,添加下一级的节点值将显示在列表中。但这似乎不起作用。我通过每次为“level”显式分配一个新的 ArrayList 来修复它。

主要问题:如果ArrayList随着元素的添加而自动增长,为什么我每次都需要分配一个新的ArrayList?为什么在级别之间调用clear()会导致顶级列表为空列表?

以下是二叉搜索树类中的相关位:

public BinarySearchTree<K extends Comparable<K>, V> {
    private Node<K,V> root;
        ...
    public List<List<V>> levelOrder() {
        // see implementation below
    }
        ...
    private static class Node<K extends Comparable<K>, V> {
        private K key;
        private V value;
        private Node<K,V> left;
        private Node<K,V> right; 
            ...
    }
}

这是 levelOrder() 方法的实现

public List<List<V>> levelOrder() {
    Queue<Node<K,V>> queue = new LinkedList<Node<K,V>>();
    List<List<V>> listOfLevels = new ArrayList<List<V>>();
    List<V> level = new ArrayList<V>();
    int currLevelCount = 1, nextLevelCount = 0;
    queue.add(root);

    while (!queue.isEmpty()) {
        Node<K,V> node = queue.remove();
        currLevelCount--;
        level.add(node.value);
        if (node.hasLeft()) {
            queue.add(node.left);
            nextLevelCount++;
        }
        if (node.hasRight()) {
            queue.add(node.right);
            nextLevelCount++;
        }
        if (currLevelCount == 0) {
            listOfLevels.add(level);
            //level.clear();    <-- why doesn't this work?
            level = new ArrayList<V>();
            currLevelCount = nextLevelCount;
            nextLevelCount = 0;
        }
    }
    return listOfLevels;
}

最佳答案

如果您对 level 列表调用 clear,则会清除刚刚添加到 listOfLevels 中的列表,然后您开始重新使用它。

由于当您调用 clear 而不是创建新的数组列表时,您从未使用 new ArrayList() 分配新的 level 列表,因此您有效地一遍又一遍地使用相同的列表。

由于您每次都会清除它,因此 listOfLevels 下的列表中永远不会有值。

调用new ArrayList而不是clear确实是正确的解决方案。

关于java - BST 层级顺序遍历 list.clear() and list = new ArrayList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33530299/

相关文章:

ios - 所有对以编程方式创建的 subview 的引用都应该声明为弱吗?

java - 根据变量对自定义 Java 类的数组列表进行排序

grails - GORM - 使用 HQL 获取 map 列表中的结果

java - SQLite 设置最大行数还是只更新相同的行数?

java - 在另一个类中编译时无法识别一个类的对象

java - 填充内存数据网格 Hazelcast 的最快方法

java - 使用Spring将文件保存到资源目录

iphone - Spiky Memory "Healthy"是 App 的吗?

memory-management - spark.shuffle.safetyFraction 和 spark.storage.safetyFraction 的区别

java - 我的 2D ArrayList 输出给出累积值?