为什么堆打印的顺序不正确?

时间:2016-07-14 04:32:40

标签: java data-structures graph heap minimum-spanning-tree

我不确定为什么我的堆方法没有以正确的顺序打印堆。有人能告诉我这里我做错了什么吗?

这是我的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

我在这里做错了什么?我会非常感激任何想法..我在这里不知所措。

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的代码 - 循环中的字符串连接很慢,因为字符串是不可变的。这可能不会对少量数据产生很大影响,但总是做得更好。