在 Java 中使用 Bag 的原因
Reasons for using a Bag in Java
我目前正在学习算法和数据结构,在阅读算法书第 4 版时,我发现了 Bag
数据结构以及 Stack
和 Queue
.
在阅读了它的解释之后,我仍然不清楚为什么我更喜欢使用 Bag
(没有 remove()
方法)而不是其他数据结构,例如 Stack
,Queue
、LinkedList
还是 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
。此外,如果您关心删除顺序,您会选择 Stack
或 Queue
,它们基本上是具有特定删除顺序的 Bags
。您可以将 Bag
视为 Stack
和 Queue
的超类型,通过特定操作扩展其 api。
大多数时候,您只需要收集对象并以某种方式处理它们(迭代+元素处理)。因此,您将使用最简单的 Bag
实现,它是一个有向链表。
Bag
是可能有重复值的无序集合。将堆栈与袋子进行比较时,第一个区别是对于堆栈,
订单很重要。
Bag 只支持add
和iterate
操作。您不能从 bag-it 中删除项目,而可以从堆栈中删除元素。-。在检查容器是否真的为空之后,客户端可以遍历它的元素;由于定义未指定实际顺序,因此客户不得依赖它。
当您需要收集对象并将它们作为一个整体而不是单独处理时,袋子很有用。例如,您可以收集样本,然后计算它们的统计数据,例如平均值或标准差——顺序是
在那种情况下无关紧要。
对于优先级队列来说,一个bag就是一个优先级队列,对应哪个元素
移除(top()-Returns 并提取优先级最高的元素。)被禁用。优先队列 api 有 top
、peek
、insert
、remove
和 update
方法。可以一次查看一个元素,并且
每个元素的优先级由一个均匀分布的随机数给出。优先级也会在每次迭代时发生变化。
我目前正在学习算法和数据结构,在阅读算法书第 4 版时,我发现了 Bag
数据结构以及 Stack
和 Queue
.
在阅读了它的解释之后,我仍然不清楚为什么我更喜欢使用 Bag
(没有 remove()
方法)而不是其他数据结构,例如 Stack
,Queue
、LinkedList
还是 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
。此外,如果您关心删除顺序,您会选择 Stack
或 Queue
,它们基本上是具有特定删除顺序的 Bags
。您可以将 Bag
视为 Stack
和 Queue
的超类型,通过特定操作扩展其 api。
大多数时候,您只需要收集对象并以某种方式处理它们(迭代+元素处理)。因此,您将使用最简单的 Bag
实现,它是一个有向链表。
Bag
是可能有重复值的无序集合。将堆栈与袋子进行比较时,第一个区别是对于堆栈,
订单很重要。
Bag 只支持add
和iterate
操作。您不能从 bag-it 中删除项目,而可以从堆栈中删除元素。-。在检查容器是否真的为空之后,客户端可以遍历它的元素;由于定义未指定实际顺序,因此客户不得依赖它。
当您需要收集对象并将它们作为一个整体而不是单独处理时,袋子很有用。例如,您可以收集样本,然后计算它们的统计数据,例如平均值或标准差——顺序是 在那种情况下无关紧要。
对于优先级队列来说,一个bag就是一个优先级队列,对应哪个元素
移除(top()-Returns 并提取优先级最高的元素。)被禁用。优先队列 api 有 top
、peek
、insert
、remove
和 update
方法。可以一次查看一个元素,并且
每个元素的优先级由一个均匀分布的随机数给出。优先级也会在每次迭代时发生变化。