在 Java 中使用 Bag 的原因

Reasons for using a Bag in Java

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

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

提前致谢。

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

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

LinkedList是列表的实现,

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

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

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

示例:在 Java、LinkedList is a collection, bag, list, queue and also you can work with it as it was a stack since it support stack operations (add~addLast~push, peekLast, removeLast~pop), so you can call it also stack. The reason, why it does not implement Stack interface is, that peek method is reserved by Queue implementation which retrieves the head of the list (first element). Therefore in case of LinkedList, the "stack methods" are derived from 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 实现,它是一个有向链表。

Bag 是可能有重复值的无序集合。将堆栈与袋子进行比较时,第一个区别是对于堆栈, 订单很重要。

Bag 只支持additerate 操作。您不能从 bag-it 中删除项目,而可以从堆栈中删除元素。-。在检查容器是否真的为空之后,客户端可以遍历它的元素;由于定义未指定实际顺序,因此客户不得依赖它。

当您需要收集对象并将它们作为一个整体而不是单独处理时,袋子很有用。例如,您可以收集样本,然后计算它们的统计数据,例如平均值或标准差——顺序是 在那种情况下无关紧要。

对于优先级队列来说,一个bag就是一个优先级队列,对应哪个元素 移除(top()-Returns 并提取优先级最高的元素。)被禁用。优先队列 api 有 toppeekinsertremoveupdate 方法。可以一次查看一个元素,并且 每个元素的优先级由一个均匀分布的随机数给出。优先级也会在每次迭代时发生变化。