我不确定为什么我的堆方法没有以正确的顺序打印堆。有人能告诉我这里我做错了什么吗?
这是我的getHeap方法:
k=1
这是我的insert和upHeap方法:
public static String getHeap(ArrayBasedList<Edge> edgeList)
{
// Build the heap
insert(new Edge(-1,-1,-1));
for(int i = 1; i < edgeList.size(); i++)
{
// Insert into the heap
insert(edgeList.get(i));
}
// Print the heap
String output="";
for(int i = 1; i < edgeList.size(); i++)
{
//System.out.printf("%4d%5d\n", heap[i].getVertex1(), heap[i].getVertex2());
output+=String.format("%4d%5d\n", heap[i].getVertex1(), heap[i].getVertex2());
}
return output;
}
这是打印出我的堆的边缘:
public static void insert(Edge e)
{
heap[edgeCount] = e;
edgeCount++;
upHeap(edgeCount - 1);
}
public static void upHeap(int pos){
if(pos > 0){
if(heap[(pos-1)/2].getWeight() > heap[pos].getWeight()){
/** Temporary edge for swapping */
Edge temp = heap[pos];
heap[pos] = heap[(pos-1)/2];
heap[(pos-1)/2] = temp;
upHeap((pos-1)/2);
}
}
}
但是不正确。正确的结果如下:
0 1
1 2
2 3
1 3
0 3
我在这里做错了什么?我会非常感激任何想法..我在这里不知所措。
答案 0 :(得分:0)
这可能不是完整的答案,但是你要两次增加edgeCount
heap[++edgeCount] = e;
edgeCount++;
答案 1 :(得分:0)
一个问题是你的upHeap
方法显然正在处理你的堆,好像根节点在索引0处,但你的输出代码从索引1开始。所以你永远不会输出堆的根节点。
其次,堆的数组表示不一定按顺序存储事物。例如,将项目1,2和3插入到最小堆中可以创建数组表示[1, 3, 2]
或[1, 2, 3]
。两者都是有效的堆。通过插入创建哪一个取决于插入顺序。
如果要按顺序从堆中删除项目,则必须创建一个extractMin
方法,该方法获取堆中索引0处的项,然后重新调整堆以移动下一个最小的item为索引0并排列其余项目。通常,这是通过移动堆中的最后一项(即heap[heap.size-1]
处的项目到heap[0]
,然后将其筛选到适当的位置来完成的。
答案 2 :(得分:0)
您不会将edgeList.get(0)
添加到堆中,因此输出中缺少该边缘(很可能是打印出0 2
的边缘)。
要将所有边添加到堆中,您的第一个循环应为:
for(int i = 0; i < edgeList.size(); i++)
{
// Insert into the heap
insert(edgeList.get(i));
}
要打印出第二个循环所需的所有边缘:
StringBuilder output=new StringBuilder();
for(int i = 1; i <= edgeList.size(); i++)
{
//System.out.printf("%4d%5d\n", heap[i].getVertex1(), heap[i].getVertex2());
output.append(String.format("%4d%5d\n", heap[i].getVertex1(), heap[i].getVertex2()));
}
return output.toString();
此循环从1变为edgeList.size()
,因为您的堆似乎包含不应打印的根元素。
我也改变了从字符串连接到使用StringBuilder
的代码 - 循环中的字符串连接很慢,因为字符串是不可变的。这可能不会对少量数据产生很大影响,但总是做得更好。