我如何得到一个PriorityQueue排序我希望它排序的东西?
我正在寻找优先级队列或堆数据结构的.NET实现
优先级队列是比简单排序提供更多灵活性的数据结构,因为它们允许新元素以任意间隔进入系统.将新作业插入优先级队列比在每次到达时重新排序所有内容更具成本效益.
基本优先级队列支持三种主要操作:
- 插入(Q,X).给定具有密钥k的项x,将其插入优先级队列Q.
- 查找-最小(Q).返回指向其键值小于优先级队列Q中任何其他键的项的指针.
- 删除 - 最小(Q).从密钥最小的优先级队列Q中删除该项
除非我在错误的地方寻找,否则框架中没有一个.有人知道一个好的,或者我应该自己动手?
默认的stl优先级队列是Max 1(Top函数返回最大的元素).
为简单起见,它说它是int值的优先级队列.
我在整数Java中有优先级队列:
PriorityQueue<Integer> pq= new PriorityQueue<Integer>();
Run Code Online (Sandbox Code Playgroud)
当我打电话时,pq.poll()我得到最小元素.
问题:如何更改代码以获取最大元素?
Dijkstra的算法教给我如下
while pqueue is not empty:
distance, node = pqueue.delete_min()
if node has been visited:
continue
else:
mark node as visited
if node == target:
break
for each neighbor of node:
pqueue.insert(distance + distance_to_neighbor, neighbor)
Run Code Online (Sandbox Code Playgroud)
但是我一直在阅读关于算法的一些阅读,我看到的很多版本都使用了reduce-key而不是insert.
为什么会这样,这两种方法之间有什么区别?
algorithm dijkstra priority-queue graph-algorithm data-structures
在PresentationCore.dll的.NET Framework中,有一个泛型PriorityQueue<T>类,其代码可以在这里找到.
我写了一个简短的程序来测试排序,结果不是很好:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using MS.Internal;
namespace ConsoleTest {
public static class ConsoleTest {
public static void Main() {
PriorityQueue<int> values = new PriorityQueue<int>(6, Comparer<int>.Default);
Random random = new Random(88);
for (int i = 0; i < 6; i++)
values.Push(random.Next(0, 10000000));
int lastValue = int.MinValue;
int temp;
while (values.Count != 0) {
temp = values.Top;
values.Pop();
if (temp >= lastValue)
lastValue = temp;
else
Console.WriteLine("found sorting error");
Console.WriteLine(temp);
}
Console.ReadLine();
} …Run Code Online (Sandbox Code Playgroud) 我试图声明一个priority_queue of nodes,bool Compare(Node a, Node b)用作比较器函数(在节点类之外).
我现在拥有的是:
priority_queue<Node, vector<Node>, Compare> openSet;
Run Code Online (Sandbox Code Playgroud)
出于某种原因,我得到了 Error: "Compare" is not a type name
将声明更改为 priority_queue <Node, vector<Node>, bool Compare>
给我 Error: expected a '>'
我也尝试过:
priority_queue<Node, vector<Node>, Compare()> openSet;
priority_queue<Node, vector<Node>, bool Compare()> openSet;
priority_queue<Node, vector<Node>, Compare<Node, Node>> openSet;
Run Code Online (Sandbox Code Playgroud)
我应该如何正确地宣布我的priority_queue?
我正在尝试使用a PriorityQueue来命令对象Comparator.
这可以很容易地实现,但是对象类变量(比较器计算优先级)可能在初始插入后发生变化.大多数人都提出了删除对象,更新值并再次重新插入的简单解决方案,因为这是优先级队列的比较器付诸行动的时候.
除了在PriorityQueue周围创建一个包装类之外,还有更好的方法吗?
由于两者std::priority_queue和std::set(和std::multiset)都是存储元素的数据容器,并允许您以有序的方式访问它们,并且具有相同的插入复杂性O(log n),因此使用一个优于另一个(或者,什么样的情况需要一个)或者其他?)?
虽然我知道底层结构是不同的,但我对它们的实现差异并不那么感兴趣,因为我在比较它们的性能和适用于各种用途.
注意:我知道集合中没有重复.这就是我之所以提到的原因,std::multiset因为它具有与之完全相同的行为,std::set但可以在允许存储的数据作为相等元素进行比较的情况下使用.所以,请不要评论单/多键问题.
我正在寻找有关如何有效实现二进制堆的信息.我觉得应该有一篇关于有效实现堆的好文章,但我还没找到.事实上,我已经无法找到任何有关超出基础知识的有效实现的资源,例如将堆存储在数组中.我正在寻找制作快速二进制堆的技术,超出我在下面描述的那些.
我已经编写了一个比Microsoft Visual C++和GCC的std :: priority_queue或使用std :: make_heap,std :: push_heap和std :: pop_heap更快的C++实现.以下是我在实现中已经涵盖的技术.我自己只想出了最后两个,尽管我怀疑这些是新想法:
(编辑:添加了关于内存优化的部分)
相反,我们可以在顶部元素所在的堆中留一个洞.然后我们通过迭代地移动较大的孩子来将那个洞向下移动.这需要我们经过的每个级别只有1个比较.通过这种方式,洞将成为一片叶子.此时,我们可以将最右下方的叶子移动到孔的位置,并将该值向上移动,直到堆属性恢复为止.由于我们移动的值是一片叶子,我们不希望它在树上移动很远.所以我们应该期待比log n更多的比较,这比以前更好.
&(p[i]) == static_cast<char*>(p) + sizeof(T) * i
Run Code Online (Sandbox Code Playgroud)
并且编译器必须执行此计算以获得p [i].sizeof(T)是编译时常量,如果sizeof(T)是2的幂,则可以更有效地进行乘法.通过添加8个填充字节以将sizeof(T)从24增加到32,我的实现变得更快.降低缓存效率可能意味着这对于足够大的数据集来说并不是一个胜利.
&(p[i]) == static_cast<char*>(p) + sizeof(T) * i == static_cast<char*>(p) + j
Run Code Online (Sandbox Code Playgroud)
然后,j值的左子和右子公式分别变为2*j和2*j + sizeof(T).父公式有点棘手,除了将j值转换为i值之外,我还没有找到方法做到这一点,如下所示:
parentOnJ(j) = parent(j/sizeof(T))*sizeof(T) == (j/(2*sizeof(T))*sizeof(T)
Run Code Online (Sandbox Code Playgroud)
如果sizeof(T)是2的幂,那么这将编译为2个移位.这比使用索引i的普通父亲多1次操作.然而,我们然后在查找上保存1个操作.因此,净效应是找到父母用这种方式花费相同的时间,而左子和右子的查找变得更快. …
c++ performance computer-science priority-queue data-structures
priority-queue ×10
c++ ×4
java ×3
.net ×2
algorithm ×2
c# ×2
collections ×1
dijkstra ×1
heap ×1
performance ×1
sorting ×1
std ×1
stl ×1