支持Enque,Dequeue,Peak,Min和Max操作的队列的正确数据结构是什么,并在O(1)时间内执行所有这些操作。
最明显的数据结构是链表,但Min,Max操作将是O(n)。 Priority Queue是另一个完美的选择,但Enqueue,Dequeue应该以Queue的正常方式工作。 (FIFO)
另一个想到的选择是Heap,但我无法弄清楚如何使用Heaps设置具有Min,Max操作的队列。
非常感谢任何帮助。
答案 0 :(得分:7)
任何可以在O(1)时间内检索Min
或Max
的数据结构都需要在每Insert
上花费至少O(log n )和Remove
以部分排序的顺序维护元素。实现此目的的数据结构称为优先级队列。
基本优先级队列支持Insert
,Max
和RemoveMax
。有许多方法可以构建它们,但binary heaps work best。
使用单个优先级队列支持所有Insert
,Min
,RemoveMin
,Max
和RemoveMax
会更复杂。本文描述了一种使用二进制堆改编的单一数据结构的方法:
Atkinson,Michael D.,et al。 “Min-max heaps and generalized priority queues.”ACM 29.10(1986):996-1000的通讯。
速度快且内存效率高,但需要很多小心才能正确实施。
答案 1 :(得分:6)
如果min()和max()实际更改结构,则无法设计您寻找的数据结构。如果min()和max()与peek()类似,并提供只读访问权限,那么你应该按照this question中的步骤,添加另一个类似于min()操作使用的deque来使用在max()操作中。本答案的其余部分假设min()和max()实际删除相应的元素。
由于您需要enqueue()和dequeue(),因此必须按到达顺序(FIFO)添加和删除元素。一个简单的双端队列(链接或使用循环向量)将在O(1)中提供此功能。
但要添加的元素可能会改变当前的min()和max();但是,删除后,应恢复旧的min()和max()值...除非它们在过渡期间被删除。此限制会强制您以某种方式对元素进行排序。任何排序结构(最小堆,最大堆,平衡二叉树,......)都需要至少O(log n)才能找到新到达的位置。
最好的办法是将平衡二叉树(min()和max())与双向链表配对。您的树节点将存储一组指向列表节点的指针,按照您在min()和max()中使用的任何键进行排序。在Java中:
// N your node class; can return K, comparable, used for min() and max()
LinkedList<N> list; // sorted by arrival
TreeMap<K,HashMap<N>> tree; // sorted by K
list
的末尾添加一个新节点,并通过其键将该节点添加到其中的HashMap
tree
中的节点。 O(log n)。list
的开头删除该节点,并从树中的节点中的HashMap中删除该节点。 O(log n)。如果您知道所有密钥都是唯一的,则可以简化此操作(通过删除HashMap)。但是,这不会影响渐近成本:它们都会保持不变。
实际上, O(log n)和 O(1)之间的差异太小,以至于C ++的STL中的默认地图实现是 O( log n)-based(树而不是哈希)。
答案 2 :(得分:1)
此结构不存在!
有一种简单的方法可以批准这个结论。
众所周知,排序问题的复杂性是 O(nlogn)。 但如果你说的结构存在,就会有一个排序解决方案:
这意味着排序问题可以通过O(n)解决。但它是不可能。
答案 3 :(得分:-2)
假设:
你只关心性能而不关心空间/记忆/ ......
解决方案:
索引是一个集合,而不是列表(适用于列表,但可能需要一些额外的爱)
你可以并排排队和哈希表。
示例:
让我们说订单是5 4 7 1 8 3
队列 - &gt; 547813
哈希表 - &gt; 134578
入队:
1)获取您的对象,并插入右侧存储桶的哈希表中.Min / Max将始终是第一个和最后一个索引。 (参见排序哈希表)
2)接下来,像往常一样插入你的队列。
3)你可以/应该把这两者联系起来。一种想法是使用哈希表值作为指向队列的指针。
具有大型哈希表的两个操作都将是O(1)
出列:
1)弹出第一个元素O(1)
2)从哈希表O(1)
中删除元素最小/最大:
1)查看你的哈希表。根据所使用的语言,理论上你可以通过查看表格的头部或表格的尾部来找到它。
为了更好地解释已排序的哈希表,https://stackoverflow.com/questions/2007212
注意强>: 我想指出,没有“正常”的数据结构可以满足您的需求。但是,这并不意味着它是不可能的。如果您打算尝试实现数据结构,很可能您必须根据需要进行操作,并且无法使用当前可用的库。你可能不得不考虑使用像汇编这样的非常低级的语言来实现这一目标,但是如果你对这些语言有好处的话,也许C或Java也许可以。
祝你好运<强> EDITED 强>: 我没有解释排序的哈希表,所以添加了一个链接到另一个SO来解释它们。