Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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/9/javascript/443.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_Sorting_Data Structures_Set_Priority Queue - Fatal编程技术网

Algorithm 持续更新优先级队列的最佳算法/数据结构

Algorithm 持续更新优先级队列的最佳算法/数据结构,algorithm,sorting,data-structures,set,priority-queue,Algorithm,Sorting,Data Structures,Set,Priority Queue,我需要经常在不断更新的集合中找到最小值对象。我需要具有优先级队列类型的功能。最好的算法或数据结构是什么?我曾想过拥有一个排序的树/堆,每次更新对象的值时,我都可以删除该对象,并将其重新插入树/堆中。有没有更好的方法来实现这一点?引用: 为了提高性能,优先级队列通常使用堆作为优先级队列 主干,为插入和删除提供O(对数n)性能,以及 O(n)开始构建。或者,当一个自平衡二进制 使用搜索树,插入和删除也需要O(logn)时间, 尽管从现有的元素序列构建树需要O(n 对数n)时间;这是一种典型的情况,人

我需要经常在不断更新的集合中找到最小值对象。我需要具有优先级队列类型的功能。最好的算法或数据结构是什么?我曾想过拥有一个排序的树/堆,每次更新对象的值时,我都可以删除该对象,并将其重新插入树/堆中。有没有更好的方法来实现这一点?

引用:

为了提高性能,优先级队列通常使用堆作为优先级队列 主干,为插入和删除提供O(对数n)性能,以及 O(n)开始构建。或者,当一个自平衡二进制 使用搜索树,插入和删除也需要O(logn)时间, 尽管从现有的元素序列构建树需要O(n 对数n)时间;这是一种典型的情况,人们可能已经可以访问 这些数据结构,例如使用第三方或标准库


如果您正在寻找更好的方法,那么优先级队列中的对象肯定有一些特殊之处。例如,如果键是从1到10的数字,基于计数排序的方法可能优于通常的方法。

< P>如果您的应用程序看起来像在离散事件模拟中重复选择下一个预定事件,那么您可以考虑在例如和…中列出的选项。后面的文章总结了该领域不同实现的结果,包括其他评论和答案中考虑的许多选项,搜索将发现该领域的大量论文。优先级队列开销确实会影响模拟的实时运行次数,如果您希望模拟需要数周实时时间的内容,这一点非常重要。

为了简单起见,二进制堆很难被击败,但它的缺点是减少关键点所需的O(n)时间。我知道,标准参考文献说是O(logn),但首先你必须找到这个项目。这是标准二进制堆的O(n)

顺便说一下,如果您确实决定使用二进制堆,那么更改项的优先级不需要删除和重新插入。您可以更改项目的优先级,然后根据需要对其进行冒泡或筛选

如果reduce key的性能很重要,那么一个好的替代方案是a,它在理论上比Fibonacci堆慢,但由于常数因子较低,更容易实现,并且在实践中比Fibonacci堆快。在实践中,配对堆与二进制堆相比更具优势,并且如果执行大量的减少密钥操作,其性能将优于二进制堆


您还可以将二进制堆与字典或哈希映射相结合,并使用该项在堆中的位置更新字典。这可以让您更快地减少关键点,但会消耗更多内存并增加其他操作的常数因子。

值是什么类型的?有多少项?值的范围是多少?@user3473949您是否尝试过使用存储桶而不是优先级队列?我的意思是为每个值存储一个具有该值的项目的链接列表。修改键就是从一个列表中删除该项并将其添加到另一个列表中。如果你保持一个指向最小非空桶的指针,你可以在O(1)中找到它。当指针指向的bucket变空时,维护该指针的成本可能会稍高一些,但这只是对最多100个指针的线性扫描,很容易放入L1,因此这也非常便宜(在您的场景中,min可能不会经常更改)@NiklasB.:Delete min可以通过使用(位压缩)来加快速度布尔值的向量,说明哪些bucket是非空的,并快速找到其中最不重要的集合位。你说“不断更新”,但更新的种类非常重要。插页?DeleteMins?任意删除?合并减量键?增加密钥?其他的?实际上有O(1)减少键的堆(不确定是否增加),但我猜这些堆有恒定的因素使它们增加impractical@NiklasB.:是的,例如有,但据我所知,由于常数因子很大,它们是不切实际的。