当前位置: 首页 > 知识库问答 >
问题:

BST级顺序遍历列表。clear()和list=newarraylist

蒙华翰
2023-03-14

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

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

levelOrder()方法将返回

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

问题:在实现中,我声明了一个名为“listOfLevels”的顶级列表来保存级别列表,以及一个名为“level”的较低级别列表来存储每个级别上的节点(我打算在各个级别上清除和重用这些节点)。然而,我注意到,如果我调用列表。“level”上的clear()方法将其添加到“listOfLevels”后,我会在“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;
}

共有2个答案

元叶秋
2023-03-14

当您将ArrayList保存到ArrayList列表时,您并没有制作副本,因此它保存的是同一个变量。这是因为ArrayList是指向内存中某个点的指针;这才是真正被拯救的。通过清除ArrayList,它会清除内存,这也会影响列表ArrayList中保存的内存位置。用你的新线代替清晰的线。

魏澄邈
2023-03-14

如果您在级别列表上调用清除,您正在清除刚刚添加到listOfLevels的列表,然后您开始重新使用它。

因为当您调用Clear而不是创建一个新的arraylist时,您从来没有用new ArrayList()分配一个新的级别列表,所以您实际上是在一遍又一遍地使用同一个列表。

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

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

 类似资料:
  • 我想在级别顺序遍历中打印出BST。但是我以这种奇怪的方式得到了输出。此外,我使用Java可视化工具来检查我的算法,没有线索,因为可视化工具没有说明多个实例。我在想,要么我的变量没有正确地添加到我的实例中,要么没有添加到

  • 二叉树的预序遍历是{8,5,9,7,1,12,4,11,3},其顺序是{9,5,1,7,12,8,4,3,11}。用它构造二叉树并执行级别顺序遍历。最后构造一个二叉搜索树(BST),从左到右依次获取在上述级别顺序遍历中出现的键值。这个BST的级别顺序遍历是什么?

  • 问题内容: 我创建了一个队列,其中包含一些对象,这些对象要按照它们在队列中的放置顺序进行迭代(第一个对象放在队列中,第二个对象放在队列中,第三个对象…) 我看到了一种在线执行此操作的方法,但不确定是否可以确保以正确的顺序访问队列中的对象? 谢谢您的帮助。 问题答案: 这取决于您使用哪种实现。 例如,保证迭代将以FIFO(插入)顺序返回元素。这是因为它实现了接口。 但是一般来说,其他类型的队列不一定

  • 我正试图弄清楚如何使用树遍历来唯一地识别一棵树,问题的关键似乎是这棵树是香草二叉树(BT),还是它也有更严格的规定二进制搜索树(BST)。这篇文章似乎表明,对于BT,单一的顺序、前序和后序遍历不会唯一地识别树(在这种情况下唯一地意味着键的结构和值)。以下是文章的快速摘要: BTs 1。我们可以用前序-序和后序-序唯一地重构BT。 2。如果我们还规定遍历跟踪节点的空子节点,那么我们也可以使用前序后序

  • 我正在尝试对二叉树进行级别顺序遍历。但诀窍是代替正常的级别顺序遍历,我想做另一种选择。对于例如。 普通等级顺序遍历 : 我要找的是我们打印根。现在,对于每一个偶数级,我都想逆时针旋转,对于每奇数级,都会顺时针旋转: 对于这种遍历,输出应该是: 这是我到目前为止尝试的,但这产生的输出与我试图实现的输出略有不同: 该程序产生以下输出: < code>1 3 2 5 4 7 6 10 11 9 8 我需

  • 输入是一个列表列表。请看下面。文件名是一个列表,包含的名称与列表中的列表数量相同(,,) 每个名称都附加到路径中:-- 程序在遍历列表时遍历包含路径的列表,并打印路径及其文件名。我希望输出是--。然而,我得到了下面的输出。请查看输入后的输出 输入 输出 我希望输出是-- 然而,我得到的结果如下: 我无法理解为什么在遍历列表时不能使用文件名遍历路径列表。我希望这有助于澄清问题。有人能帮忙吗? 我已经