Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 实现双端优先级队列的最佳方法是什么?_Algorithm_Data Structures_Big O_Priority Queue_Heapsort - Fatal编程技术网

Algorithm 实现双端优先级队列的最佳方法是什么?

Algorithm 实现双端优先级队列的最佳方法是什么?,algorithm,data-structures,big-o,priority-queue,heapsort,Algorithm,Data Structures,Big O,Priority Queue,Heapsort,我希望实现具有以下约束的双端优先级队列: 需要在固定大小的数组中实现..比如说100个元素..如果数组已满后需要添加新元素,则需要删除最旧的元素 需要O(1)中的最大值和最小值 如有可能,插入O(1) 如果可能,移除O(1)中的最小值 如果可能,清除O(1)中的空/init状态 此时数组中元素数的计数,单位为O(1) 我希望以上5个操作都是O(1),但不可能在同一个实现中对所有操作都使用O(1)。3个操作上至少O(1)和其他2个操作上的O(log(n))就足够了 如果能为这种实现提供任何指针

我希望实现具有以下约束的双端优先级队列:

  • 需要在固定大小的数组中实现..比如说100个元素..如果数组已满后需要添加新元素,则需要删除最旧的元素

  • 需要O(1)中的最大值和最小值

  • 如有可能,插入O(1)

  • 如果可能,移除O(1)中的最小值

  • 如果可能,清除O(1)中的空/init状态

  • 此时数组中元素数的计数,单位为O(1)

我希望以上5个操作都是O(1),但不可能在同一个实现中对所有操作都使用O(1)。3个操作上至少O(1)和其他2个操作上的O(log(n))就足够了

如果能为这种实现提供任何指针,我们将不胜感激。

A将在
O(logn)
中为您提供插入和移除最小值,在
O(1)
中为您提供其他最小值

唯一棘手的部分是在数组满后删除最旧的元素。为此,请保留另一个阵列:

time[i] = at what position in the heap array is the element 
          added at time i + 100 * k. 
每100次迭代,就增加
k

然后,当数组第一次填充时,您移除
heap[time[0]]
,当数组第二次填充时,您移除
heap[time[1]
,…,当数组第100次填充时,您环绕并再次移除
heap[time[0]
。当数组第
k次填充时,您可以删除堆[time[k%100]
(100是您的数组大小)

插入和删除元素时,请确保同时更新
时间
数组


如果您知道任意元素的位置,可以在
O(log n)
中删除任意元素:只需将其与堆数组中的最后一个元素交换,并筛选已交换的元素。

如果您绝对需要将max和min设置为O(1),那么您可以创建一个链接列表,在其中不断跟踪min、max、,然后将所有节点链接到某种树结构,可能是一个堆。Min、max和size都是常量,因为找到任何节点都是O(logn),所以insert和remove都是logn。清除将是微不足道的。

为此有许多专门的数据结构。一个简单的数据结构是min-max堆,它被实现为二进制堆,其中层在“min layers”(每个节点小于或等于其子代)和“max layers”(每个节点大于或等于其子代)之间交替。最小值和最大值可以在时间O(1)中找到,并且与标准二进制堆一样,可以在每次O(logn)时间内完成排队和退队

您还可以使用,这是任务的另一个专用优先级队列

或者,您可以使用两个优先级队列—一个按升序存储元素,另一个按降序存储元素。无论何时插入值,都可以将元素插入两个优先级队列,并让每个队列存储指向另一个队列的指针。然后,无论何时将最小值或最大值出列,都可以从另一堆中删除相应的元素

作为另一种选择,您可以使用平衡的二进制搜索树来存储元素。然后可以在时间O(logn)(或者如果缓存结果,则为O(1))中找到最小值和最大值,并且可以在时间O(logn)中完成插入和删除。如果使用C++,则可以使用<代码> STD::MAP<代码>,然后使用<代码>开始()和代码>和<代码> ReXORE()/<代码>分别获得最小值和最大值。
希望这有帮助

如果您的队列是固定大小的,则O表示法没有意义。任何O(logn)或甚至O(n)操作本质上都是O(1),因为n是固定的,所以您真正想要的是一个对给定数据集快速的算法。可能两个并行的传统堆优先级队列就可以了(一个用于高优先级,一个用于低优先级)


如果您对所拥有的数据类型了解得更多,您可能会制作出更具特殊用途的产品。

您尝试过什么吗?至少O(1)中的clear to empty/init状态对于了解基本数据结构的人来说是非常重要的:(@fally ya甚至还有计数..只需跟踪它…我只是将操作和时间复杂性明确化:),因此建议某个特定实现的人将清楚地知道预期膨胀,您不能让insert和extract minimum/maximum为常量或摊销常量时间,因为这将意味着一个线性时间排序算法。所有这些都假设您的密钥不是整数之类的,而是带有比较运算符的黑盒。如何从O(1)中的二进制堆中同时找到最小值和最大值,我想我们只能在O(1)中找到其中一个,这取决于它是最小值还是最大值堆。@Medicine-保留两个堆,或者查看templatetypedef的答案。好的,要删除最小值,我可以在O中删除(log(n))从最小堆中..从最大堆中删除相同的元素需要额外的努力吗heap@Medicine-相同,
O(logn)
<代码>2*O(对数n)=O(对数n)。通过保持与
time
类似的数组,可以看到一个元素在另一个元素中的位置。但是,如果使用最小-最大堆,工作可能会少一些。我正在考虑最小-最大堆,但需要一个参考实现。谢谢,需要的最大帮助是在C或C++@Medicine中干净地实现最小-最大堆-我用其他几个解决方案更新了我的答案。最后一个解决了一个简单的C++思想。