【发布时间】:2015-11-04 19:21:39
【问题描述】:
上下文:我在 Java 中创建了一个 BinarySearchTree 类作为学习练习,因为我是 Java 新手。我目前正在编写一种用于级别顺序遍历(BFS)的方法,该方法返回每个级别的节点值列表列表,其中顶级列表索引表示级别编号,每个索引处的下级列表包含该级别的节点值,例如对于这棵树
F
/ \
/ \
/ \
B G
/ \ \
/ \ \
A D I
/ \ /
C E H
levelOrder() 方法会返回
[[F], [B, G], [A, D, I], [C, E, H]]
问题:在实现中,我声明了一个名为“listOfLevels”的顶级列表来保存级别列表,并声明一个名为“级别”的较低级别列表来存储每个级别的节点(我打算跨级别清除和重用)。但是,我注意到如果在将它添加到“listOfLevels”之后在“level”上调用 List.clear() 方法,我会在“listOfLevels”中得到空列表作为方法的返回值,就像这样
[[], [], [], []]
我不确定为什么会发生这种情况。根据 ArrayList 文档,“当元素被添加到 ArrayList 时,它的容量会自动增长”,所以我认为在使用 clear() 方法清除上一层的值后,从下一层添加节点值会显示在列表中。不过,这似乎不起作用。我通过每次显式为“级别”分配一个新的 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;
}
【问题讨论】:
标签: java memory-management arraylist binary-search-tree tree-traversal