【问题标题】:ArrayDeque vs LinkedList as Queue for level-order traversalArrayDeque vs LinkedList 作为级别顺序遍历的队列
【发布时间】:2019-11-08 02:09:24
【问题描述】:

在这种情况下,ArrayDeque 是否应该优先于 LinkedListWhy is ArrayDeque better than LinkedList

在我看来,我应该使用 LinkedList 而不是 ArrayDeque,因为有很多 polloffer 在这个算法中进行操作,并且没有随机访问元素。

 public ArrayList<ArrayList<Integer>> levelOrder(TreeNode a) {
    Queue<TreeNode> q = new LinkedList<>();  // new ArrayDeque<>() ???
    q.offer(a);
    ArrayList<ArrayList<Integer>> ans = new ArrayList<ArrayList<Integer>>();
    while (q.peek() != null){ //returns null if empty
        ArrayList<Integer> list = new ArrayList<>();
        int n = q.size();
        for (int i = 0; i < n; i++){
            TreeNode node = q.poll();
            list.add(node.val);
            if (node.left != null) {
                q.offer(node.left);
            }
            if (node.right != null) {
                q.offer(node.right);
            }
        }
        ans.add(list);
    }
    return ans;
}

【问题讨论】:

标签: java algorithm data-structures queue


【解决方案1】:

在将ArrayDequeLinkedList 视为双向队列时,需要考虑许多权衡。

一般来说LinkedList类型有以下优点:

  • 添加元素的成本是最坏情况下的 O(1),因此任何单独的插入都不会花费太多时间。
  • 从末端删除元素的成本是最坏情况 O(1),因此单个删除不会花费太多时间。

一般来说,LinkedList 类型有以下主要缺点:

  • 由于LinkedList 中的元素不一定连续存储在内存中,LinkedList 的引用局部性较差,访问可能会导致更多的缓存未命中,从而降低性能。

一般来说ArrayDeque类型有以下优点:

  • 由于元素是连续存储的,ArrayDeque 具有很好的引用局部性,因此元素访问通常会产生很少的缓存未命中,从而带来出色的性能。

一般来说ArrayDeque有以下缺点:

  • 尽管ArrayDeque 上的任何 n 次操作序列都将花费 O(n) 时间,但当插入时超出数组容量时,ArrayDeque 可能必须执行 O(n) 工作来复制元素。因此,ArrayDeque 每次操作的最坏情况性能比LinkedList 慢。
  • 同样,如果数组容量在删除时降得太低,调整数组大小可能需要 O(n) 时间,不过,和以前一样,ArrayDeque 上的任何一系列 n 操作都需要时间 O(n )。

在您的特定用例中,由于您只关心级别顺序遍历的端到端效率,而不是从队列中单独添加或删除元素的成本,因此它可能会更快使用ArrayDeque 而不是LinkedList。从某种意义上说,LinkedList 类型通常只有在您需要在执行的每个操作上都具有良好的最坏情况性能时才会更好,而这里的情况并非如此。当您只关心端到端运行时,ArrayDeque 通常性能更高。

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-20
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多