【问题标题】:What are the advantages of using a Bag data structure over others like Set or Linkedlist for a graph implementation API对于图实现 API,使用 Bag 数据结构相对于 Set 或 Linkedlist 等其他数据结构有哪些优势
【发布时间】:2015-02-23 07:38:58
【问题描述】:

这是与问题相关的示例代码。此 API 尝试将具有邻接列表表示形式的图实现为由图中每个顶点索引的 Bags 数组。

public class Graph{

private final int V;          //no. of vertices
private Bag<Integer>[] adj;  // A bag for each vertex to store all adjacent vertices
.
.
.
}

在这里使用 Bag 比链表或 Set 有什么优势吗?我知道袋子是无序的,但既然它们不能节省我们的时间或空间,为什么还要使用无序列表呢?

【问题讨论】:

  • 我不认为这是一个很好的代表。图通常由邻接矩阵或每个顶点的邻接列表实现。邻接列表不应该有重复,所以Bag 没有真正的优势,它可能会在不应该存在的地方引入重复。

标签: java data-structures bag


【解决方案1】:

每种数据结构都可以在不同的情况下使用:

Set(特别是HashSet)可以是无序的唯一元素列表。另一方面,Bags 是多集(可能包含重复元素的无序集合)。

至于LinkedList,它们提供了更简单的链接操作,即在不同的地方添加元素,更容易(恒定时间)。

【讨论】:

  • @nash_at 在链表中的特定位置添加元素只有在我们已经有一个指向该位置的迭代器时才会保持不变。很多时候,我们必须在线性时间内迭代到该位置。
  • @SteveM 是的,你是对的,这就是为什么我想强调更简单的链接操作:)
【解决方案2】:

Bag 可能使用二叉搜索树或哈希表实现,给我们 O(log n) 或 O(1) 搜索。链表将提供 O(n) 次搜索。

Set 只允许唯一元素,因此如果您需要存储重复项,则需要一个 Bag。 Java Collections 库中的 TreeSet 或 HashSet 将分别给我们 O(log n) 或 O(1) 搜索。

一般来说,当你经常需要进行搜索或删除操作时,Set 或 Bag 接口会更合适。如果您只需要添加到集合的末尾并对其进行迭代,则不会有太大区别。

【讨论】:

  • 这是Graph数据结构的实际代码,因为代码是由非常知名的教授编写的,所以这个问题有一个重要的观察。我也在调查,看看有没有什么重要的发现。
  • delete 对包进行操作?袋子不支持移除物品。见algs4.cs.princeton.edu/13stacks
  • @JanacMeena Bag 的一些实现确实支持删除元素。
【解决方案3】:

bag、queue 和 stack 等数据类型在下一个要删除或检查的对象的规范上有所不同。

包是不支持删除项目的集合。 Bags 的目的是为客户提供收集物品然后遍历它们的能力。

API 包 (Java)

public class Bag<Item> implements Iterable<Item>
    Bag() // creates an empty bag
    void add(Item item)
    boolean isEmpty()
    int size()

Bag.java

import java.util.Iterator;
import java.util.NoSuchElementException;

public class Bag<Item> implements Iterable<Item> {
    private Node<Item> first;
    private int n;

    private static class Node<Item> {
        private Item item;
        private Node<Item> next;
    }

    public Bag() {
        first = null;
        n = 0;
    }

    public boolean isEmpty() {
        return first == null;
    }

    public int size() {
        return n;
    }

    public void add(Item item) {
        Node<Item> oldfirst = first;
        first = new Node<Item>();
        first.item = item;
        first.next = oldfirst;
        n++;
    }

    public Iterator<Item> iterator()  {
        return new LinkedIterator(first);
    }

    private class LinkedIterator implements Iterator<Item> {
        private Node<Item> current;

        public LinkedIterator(Node<Item> first) {
            current = first;
        }

        public boolean hasNext()  { return current != null;                     }
        public void remove()      { throw new UnsupportedOperationException();  }

        public Item next() {
            if (!hasNext()) throw new NoSuchElementException();
            Item item = current.item;
            current = current.next;
            return item;
        }
    }
}

【讨论】:

    【解决方案4】:

    除了其他答案之外,Bag 与其他无序数据结构(即 Set)之间的主要区别在于 Bags 不支持在添加项目后删除

    一个示例用例是一个特殊的日志记录系统,我们从不打算删除过去的插入。或者确保高度并发系统中的不变性。

    请参阅https://algs4.cs.princeton.edu/13stacks/ 以获得准确的描述以及袋子与其他数据结构的比较。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-16
      • 1970-01-01
      • 2011-05-24
      • 2012-04-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多