我尝试使用优先级队列在Java中实现Dijkstra算法。我已经编写了我自己使用的所有数据结构,但是我很难让优先级队列正常运行。使用较小的数据集似乎可以很好地工作,但随着我增加队列中的项目,结果变得不正确。
PriorityQueue是它自己的类,方法如下:
public void SettleNode(int i)
{
GraphNode tempnode = heap[i];
int child;
for (; i*2 <= size; i = child)
{
child = i*2;
if (child != size && heap[child].tdistance > heap[child + 1].tdistance)
child++;
if (tempnode.tdistance > heap[child].tdistance)
heap[i] = heap[child];
else
break;
}
heap[i] = tempnode;
}
public void CreateBinaryHeap()
{
for (int i = size / 2; i > 0; i--)
{
SettleNode(i);
}
}
public GraphNode PeekMin()
{
return heap[1];
}
public GraphNode Dequeue()
{
heap[1] = heap[size--];
SettleNode(1);
}
不是一次插入一个值,而是用来表示PQ的数组通过构造函数传入,然后调用CreateBinaryHeap()
方法,到目前为止一切都很好。
Dijkstras算法以这样的方式实现:我们当前正在查看的图中的节点是通过PeekMin()
方法得到的,然后使用Dequeue()
来获取PQ的最小值并得到处理完所有边缘后的下一分钟。在这两个事件之间,我正在通过边缘更改连接到currentnode的tdistance
个节点。
正确设置节点的暂定距离,调试显示调用Dequeue()
时min节点(heap [1])设置错误,因此PeekMin()
返回不正确的价值。
我可以将Dequeue()
更改为:
public GraphNode Dequeue()
{
heap[1] = heap[size--];
CreateBinaryTree();
}
我得到了正确的输出,但是这会使我的代码速度降低到不可接受的水平。