使用“提取”方法迭代地从最小堆中删除最小的元素并将其复制到指定的arrayList中,以获取排序列表的方法

时间:2018-09-26 20:22:53

标签: java heap extract heapsort

我有一个程序,该程序读取文本文件并创建许多可用于构建MIN堆的节点元素。

我正在努力的是,在正确构建Min堆之后,我应该使用'extract'方法对元素进行排序,以删除根目录中最小的元素并将其添加到单独的ArrayList中旨在按排序顺序包含元素。

当然,我们应该一次提取一个元素并将其添加到新的arraylist中,然后从剩余节点的堆中删除该元素,以便堆继续减少一个元素,而排序后的arraylist继续增加按一个元素,直到堆中没有剩余的元素。

我相信问题在于,提取最小堆的根元素之后,即使擦除方法应该通过替换覆盖已删除的根元素,根元素本身也不会被擦除,它似乎仍保留在堆中它与堆中的最后一项一起使用,然后减小堆大小,然后重新应用“ heapify”方法以恢复堆属性。

我的代码很简单,主要方法很长,但重要的部分如下:

        g = new Graph();
        readGraphInfo( g );
        DelivB dB = new DelivB(inputFile, g);


        int numElements = g.getNodeList().size();
        ArrayList<Node> ordered_nodeList = new ArrayList<Node>(15);
        ArrayList<Node> sorted_nodeList = new ArrayList<Node>(15);
        h = new Heap(ordered_nodeList, g);

        for (int i = 0; i < numElements; i++)
        {
            ordered_nodeList.add(i, g.getNodeList().get(i));

            h.Build_min_Heap(ordered_nodeList);
            System.out.println("Heap: \n");
            System.out.println("\n**********************" + "\nProg 340 line 147" +h.heapClass_toString(ordered_nodeList)); 
            //System.out.println("the " + i + "th item added at index " + i + " is: " + ordered_nodeList.get(i).getAbbrev());
        }

        for (int j = 0; j < numElements; j++)
        {
            sorted_nodeList.add(j, h.heap_Extract(ordered_nodeList));
            System.out.println("the "+j+"th item added to SORTED node list is: "+sorted_nodeList.get(j).getAbbrev()+ " "+ sorted_nodeList.get(j).getVal());
            //h.heap_Sort(ordered_nodeList);
            System.out.println("\nthe 0th remaining element in ordered node list is: " + ordered_nodeList.get(0).getVal());
            h.Build_min_Heap(ordered_nodeList);
        }

        for (Node n : sorted_nodeList)
        {
            System.out.println("sorted node list after extract method*****************\n");
            System.out.println(n.toString());
        }

我不断得到的输出如下:

the 0th remaining element in ordered node list is: 55
the 1th item added to SORTED node list is: F 55

the 0th remaining element in ordered node list is: 55
the 2th item added to SORTED node list is: F 55

the 0th remaining element in ordered node list is: 55
the 3th item added to SORTED node list is: F 55

the 0th remaining element in ordered node list is: 55
the 4th item added to SORTED node list is: F 55

the 0th remaining element in ordered node list is: 55
the 5th item added to SORTED node list is: F 55

the 0th remaining element in ordered node list is: 55
sorted node list after extract method*****************

 F
sorted node list after extract method*****************

 F
sorted node list after extract method*****************

 F
sorted node list after extract method*****************

 F
sorted node list after extract method*****************

 F
sorted node list after extract method*****************

 F

我的堆类如下:

import java.util.*;

public class Heap 
{
int heapSize;
ArrayList unordered_nodeList;
ArrayList ordered_nodeList;
Graph gr;

nodes
public Heap(ArrayList<Node> A, Graph g)
{
    unordered_nodeList = g.getNodeList();
    heapSize = unordered_nodeList.size();
    ordered_nodeList = A;
    gr = g;
}

public ArrayList getUnordered_nodeList() {
    return unordered_nodeList;
}

public void setUnordered_nodeList(ArrayList unordered_nodeList) {
    this.unordered_nodeList = unordered_nodeList;
}

public ArrayList getOrdered_nodeList() {
    return ordered_nodeList;
}

public void setOrdered_nodeList(ArrayList ordered_nodeList) {
    this.ordered_nodeList = ordered_nodeList;
}

public int getHeapSize() {
    return heapSize;
}

public void setHeapSize(int heapSize) {
    this.heapSize = heapSize;
}

//heap methods

public int Parent(ArrayList<Node> A, int i)
{
    //if (i == 1)
        //return (Integer)null;

    if (i%2 != 0)
        return i/2;

    else 
        return (i-1)/2;
}

public int Left(ArrayList<Node> A, int i)
{
    if (2*i < A.size()-1)
        return (2*i)+1;
    else
        return i;
        //return (Integer)null;
}

public int Right(ArrayList<Node> A, int i)
{
    if ((2*i)+1 < A.size()-1)
        return 2*i+2;
    else
        return i;
        //return (Integer)null;
}

public void Heapify(ArrayList<Node> A, int i)
{
    Node smallest;
    Node temp;
    int index;

    int l = Left(A,i);
    int r = Right(A,i);

    if (l <= heapSize-1 && Integer.parseInt(A.get(l).getVal()) < Integer.parseInt(A.get(i).getVal()))
    {   
        //left child is smaller
        smallest = A.get(l);
        index = l;
    }   
    else
    {   
        //parent node is smaller
        smallest = A.get(i);
        index = i;
    }   

    if (r <= heapSize-2 && Integer.parseInt(A.get(r).getVal()) < Integer.parseInt(smallest.getVal()))
    {   
        //right child is smaller
        smallest = A.get(r);
        index = r;
    }

    if (index != i)
    {   
        //if the smallest element is not the parent node
        //swap the smallest child with the parent  
        temp = A.get(i);
        A.set(i, A.get(index));
        A.set(index, temp);

        //recursively call heapify method to check next parent/child relationship
        Heapify(A, index);

        //System.out.println(this.heapClass_toString(ordered_nodeList));
    }
    //System.out.println("\n**********************" + "\nHeapify line 123" + this.heapClass_toString(ordered_nodeList));
}   

//method to construct min heap from unordered arraylist of nodes
public void Build_min_Heap(ArrayList<Node> A)
{
    int i;
    int heapSize = A.size();

    for (i = (heapSize/2); i>=0; i--)
    {   
        //System.out.println(gr.toString2() +"\n");
        //System.out.println("build heap ********** line 138" +this.heapClass_toString(ordered_nodeList));
        Heapify(A, i);
        //System.out.print(gr.toString2()+"\n");
    }       
}

//method to sort in descending order, a min heap
public void heap_Sort(ArrayList<Node> A)
{
Node temp;


    //Build_min_Heap(A);
while (A.size() > 0)
{   
    ///System.out.println("\n******************************\n heap_sort line 180" +this.heapClass_toString(ordered_nodeList));

    //for (int i = 0; i <= A.size()-1; i++)
    for(int i = A.size()-1; i >= 1; i--)
    {
        //exchange a[0] with a[i]
        temp = A.get(0);
        A.set(0, A.get(i));
        A.set(i, temp);

        //System.out.println(this.heapClass_toString(ordered_nodeList));

        //decrement heapSize
        heapSize--;

        //recursive heapify call
        Heapify(A, 0);

        System.out.println("\n******************************\n heap_sort line 203" +this.heapClass_toString(ordered_nodeList));
    }   
    System.out.println("\n******************************\n heap_sort line 206" +this.heapClass_toString(ordered_nodeList)); 
    Heapify(A, A.size()-1);
}
}


public Node heap_Extract(ArrayList<Node> A)
{

    //Node min = null;

    //if (heapSize>0)   
    //while (A.get(0) != null && heapSize > 0)  
    Node min = A.get(0);

    //min = A.get(0);
    while (heapSize>0)
    {   
        min = A.get(0);

        A.set(0, A.get(heapSize-1));

        //decrement heapSize
        heapSize--;
        Heapify(A, 0);  
    }   
    return min;
}
    //return min;

public String heapClass_toString(ArrayList A)
{
    String s = "Graph g.\n";
    if (A.size() > 0 ) 
    {
        for (int k = 0; k < A.size(); k++ )
        {
            //output string to print each node's mnemonic 
            String t = this.getOrdered_nodeList().get(k).toString();

            s = s.concat(t);        
        }   
    }
    return s;
} 

}

1 个答案:

答案 0 :(得分:1)

一个问题是您的heap_Extract()方法中的以下循环:

while (heapSize>0)
{   
    min = A.get(0);

    A.set(0, A.get(heapSize-1));

    //decrement heapSize
    heapSize--;
    Heapify(A, 0);  
} 

此循环将一遍又一遍地运行,直到堆中没有任何内容为止,然后该函数将返回最后一个设置为min的节点(如果{ {1}}正确实现)。随后的调用将看到Heapify,完全跳过循环并立即返回heapSize == 0,该值将设置为min,它仍将是原始堆中最大的元素。您应该确保每次调用A.get(0)时,此循环主体中的代码最多只能运行一次(即,它不应处于循环中,但可能应由其他条件分支语句保护)。