在STL优先队列c++中实现了reducekey
Implement decreaseKey in STL Priority Queue C++
我试图实现Prim的算法,为此我需要有一个用于优先级队列的reducekey方法(更新优先级队列中的键值)。我可以在STL优先队列中实现这一点吗?
如果它有帮助,这是我遵循的算法:
- 图G中每个顶点u的
- 设置u键为INFINITY
- 设置u的父元素为NIL
- 设置源顶点键为0
- 排队到优先队列Q图中所有顶点的键值如下
- ,而Q不为空
- if (v仍在Q) and (key(u) + weight-function(u, v) <键(v))>
- 设置u为v的父级
- 更新v的键等于key(u) + weight-function(u, v) //这部分给了我问题,因为我不知道如何实现在优先队列
- if (v仍在Q) and (key(u) + weight-function(u, v) <键(v))>
我不认为你可以在STL容器中实现它。请记住,您总是可以基于vector编写自己的堆(优先级队列),但有一种解决方法:
保持你的距离数组,比如d
。在你的优先级队列中,你把距离对和这个距离的顶点索引放在一起。当您需要从队列中删除某个值时,不需要删除它,只需在d
数组中更新您的值并将新对放入队列即可。
每次你从队列中获取新值时,检查pair中的距离是否真的那么好,就像你的数组d
一样。
时间相同O(MlogM)。内存为0 (MlogM),其中M为边数。
还有另一种方法:使用RB-Tree,它可以在O(logN)内插入和删除键,并且得到最小值。您可以在std::set
容器中找到RB-Tree的STL实现。
但是,尽管时间复杂度相同,RB-Tree的工作速度更慢,隐藏常数更大,所以它可能会稍微慢一点,appx。慢5倍。当然,这取决于数据。
对于另一种方法:优于使用std::set。您可以使用btree::btree_set(或btree::safe_btree_set)。这是一个与std::set相同的实现,由google使用B-Tree,而stl使用RB-Tree。这比std::set和O(logN)要好得多。查看性能对比:http://code.google.com/p/cpp-btree/wiki/UsageInstructions而且它占用的内存也少得多。
我不是专家,所以希望这不是太愚蠢,但是向量与lower_bound结合会很好地工作吗?
如果使用lower_bound找到插入新值的正确位置,则在构建vector时,vector总是被排序,不需要排序。当你的向量排序时,lower_bound不是一个具有对数类性能的二分搜索吗?
因为它是排序的,所以找到最小值(或最大值)是很容易的。
对于reduce key,您将执行lower_bound搜索,删除,并再次执行lower_bound以插入简化的键,这= 2个对数类操作。还不错。
或者,您可以更新键并对向量进行排序。我猜对于随机访问,它应该仍然在对数类中,但我不知道它到底是做什么的。
对于已排序的向量,如果你知道候选键小于里面的那个键,那么也许你甚至可以对向量中包含所有较小值的部分进行排序以获得更好的性能。
另一个考虑是我认为集合/映射有相当多的内存开销比向量做?
我认为大多数排序都局限于NLogN,所以2 LogN用于重新插入而不是排序可能对reduce键操作更好。
另一件事是插入向量不是那么热门,但总的来说,向量w的想法是否值得考虑?
谢谢
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 用于AVX的ln(x)的实现,m256
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在C++中,如何在类和函数(可能是模板化的)的头中编写完整的实现
- 在STL优先队列c++中实现了reducekey