【问题标题】:Reasons for using a Bag in Java在 Java 中使用 Bag 的原因
【发布时间】:2017-09-11 16:36:29
【问题描述】:

我目前正在研究算法和数据结构,在阅读《算法之书》第 4 版时,我发现了 Bag 数据结构以及 StackQueue。 在阅读了它的解释之后,我仍然不清楚我更喜欢使用Bag(没有remove() 方法)而不是其他数据结构,例如StackQueueLinkedList还是Set? 据我从书中了解到,Bag 的实现与Stack 的实现相同,只是将push() 的名称替换为add() 并删除pop() 方法。

所以Bag 的想法基本上是能够收集物品,然后遍历收集的物品,检查一个袋子是否是空的,并找出其中的物品数量。 但是在哪种情况下我最好使用Bag 而不是上述集合之一?为什么Bag 基本上没有remove() 方法?有什么具体原因吗?

提前致谢。

【问题讨论】:

    标签: java algorithm data-structures bag


    【解决方案1】:

    Stack 是具有特定移除顺序 = LIFO(后进先出)的元素集合的 ADT,允许重复,

    Queue 是具有特定移除顺序 = FIFO(先进先出)的元素集合的 ADT,允许重复,

    LinkedList是列表的实现,

    Set 是不允许重复的元素集合的 ADT,

    Bag 是允许重复的元素集合的 ADT。

    一般来说,任何包含元素的东西都是Collection。 任何允许重复的集合为Bag,否则为Set。 任何通过索引访问元素的包都是List。 在最后一个元素之后附加新元素并具有从头部(第一个索引)删除元素的方法的包是Queue。 在最后一个元素之后附加新元素并具有从尾部(最后一个索引)删除元素的方法的包是Stack

    示例:在 Java 中,LinkedList 是一个集合、包、列表、队列,您也可以像使用堆栈一样使用它,因为它支持堆栈操作 (add~addLast~push, peekLast, removeLast~pop),所以你也可以调用它stack。它没有实现Stack 接口的原因是peek 方法被Queue 实现保留,它检索列表的头部(第一个元素)。因此对于LinkedList,“堆栈方法”派生自Deque

    Bag 是否包含remove(Object) 可能取决于实现 e。 G。您可以实现自己的支持此操作的Bag 类型。您还可以实现get(int) 操作来访问指定索引上的对象。 get(int) 的时间复杂度取决于您的实现 e。 G。一个可以通过链表实现Bag,因此复杂度平均为 O(n/2),另一种通过可调整大小的数组(数组列表)通过索引直接访问元素,因此复杂度为 O( 1)。

    Bag 的主要思想是,它允许通过此集合进行复制和迭代。是否支持其他有用的操作取决于实现者的设计决策。

    使用哪一种集合类型取决于您的需要,如果不需要重复,您可以使用Set 而不是Bag。此外,如果您关心删除顺序,您会选择StackQueue,它们基本上是具有特定删除顺序的Bags。您可以将Bag 视为StackQueue 的超类型,通过特定操作扩展其api。

    大多数时候,您只需要收集对象并以某种方式处理它们(迭代 + 元素处理)。因此,您将使用最简单的Bag 实现,它是一个定向链表。

    【讨论】:

    • 感谢您提及每个人的特点,但我已经知道这些信息以及每个 ADT 能够做什么,但我的问题是 Bag 什么时候更方便优于其他 ADT?
    • @TalBuaron,把它想象成一个你不关心位置元素的列表,但你特别希望允许重复元素。
    • @TalBuaron 在您不关心集合是 FIFO 还是 FILO 时使用 Bag。当性能受到关注时,这将变得很有用,因为它可以让您选择具有与 Stack 或 Queue 不同的 BigO 特征的 Bag 的实现。
    • @M.Prokhorov ,所以Bag 是唯一允许重复且没有插入顺序的集合/数据结构?这很有趣
    • @RoshanaPitigala ADT 代表抽象数据类型
    猜你喜欢
    • 2014-06-22
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多