在 Java 中使用包的原因

2022-09-02 21:06:32

我目前正在研究算法和数据结构,当我阅读算法书第4版时,我发现了数据结构以及和。在阅读了它的解释之后,我仍然不清楚为什么我更喜欢使用a(没有方法)而不是其他数据结构,例如,,或a?据我从书中了解到的,a 的实现与 a 相同,只需替换 to 的名称并删除该方法即可。BagStackQueueBagremove()StackQueueLinkedListSetBagStackpush()add()pop()

因此,a的想法基本上是能够收集物品,然后循环访问收集的物品,检查袋子是否是空的,并找到其中的物品数量。但是在什么情况下,我最好使用上述集合之一呢?为什么a基本上没有方法?有没有具体的原因?BagBagBagremove()

提前致谢。


答案 1

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

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

LinkedList是列表的实现,

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

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

通常,任何包含元素的东西都是 。任何允许重复的集合是 ,否则它是 。通过索引访问元素的任何包都是 。在最后一个元素之后附加新元素并具有从头部(第一个索引)中删除元素的方法的Bag是 。在最后一个元素之后附加新元素并具有从尾部(最后一个索引)中删除元素的方法的Bag是 。CollectionBagSetListQueueStack

示例:在Java中,LinkedList是一个集合,包,列表,队列,并且还可以使用它,因为它是一个堆栈,因为它支持堆栈操作(~~,,~),因此您可以将其称为堆栈。它不实现 Stack 接口的原因是,该方法由队列实现保留,该实现检索列表的头部(第一个元素)。因此,在LinkedList的情况下,“堆栈方法”派生自DequeaddaddLastpushpeekLastremoveLastpoppeek

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

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

使用哪种集合类型取决于您的需要,如果不需要重复项,则可以使用 代替 。此外,如果您关心删除订单,您可以选择或基本上具有特定的删除顺序。您可以将其视为的超类型,它通过特定操作扩展其 api。SetBagStackQueueBagsBagStackQueue

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


答案 2

Bag是可能具有重复项的值的无序集合。在将烟堆与袋子进行比较时,第一个区别是对于堆叠,顺序很重要。

袋子只支持和操作。您无法从袋子中删除项目 - 可以从堆栈中删除元素。在检查容器是否实际为空后,客户端可以循环访问其元素;由于实际订单未根据定义指定,因此客户端不得依赖它。additerate

当您需要收集物品并将其作为一整套而不是单独处理时,袋子非常有用。例如,您可以收集样本,然后计算样本的统计数据,例如平均值或标准差 - 在这种情况下,顺序无关紧要。

就优先级队列而言,包是一个优先级队列,其中禁用了元素删除(top()-Return并提取具有最高优先级的元素。优先级队列 API 具有、、和方法。可以一次查看一个元素,每个元素的优先级由均匀分布中的随机数给出。优先级在每次迭代时也会发生变化。toppeekinsertremoveupdate