用Java创建最小的对象堆

时间:2018-03-27 22:38:21

标签: java data-structures heap

我正在尝试用Java创建一个min heap。我按照site的算法进行了操作。但是,在该网站上,他们传递整数,我想传入对象。我的代码几乎可以工作,但我应该得到这个输出:

  

父母:3个孩子:5个孩子:6个

     

父母:5名左子女:9名右儿:84

     父母:6个孩子:19个孩子:17个

     

父母:9个孩子:22个孩子:10个

但我得到了这个:

  父母:6个孩子:9个孩子:9个

     父母:9个孩子:12个孩子:45个

     

父母:9名左儿童:13名右儿:22

所以我错过了一些数字并且堆不正确。我看了一切,看起来逻辑应该是相同的。我知道问题出在MiniHeap.java中,但我将所有代码都粘贴在这个项目中以防万一。

MinHeap.java:

package javaapplication2;
public class MinHeap {

    private Node[] NHeap;
    private int size;
    private int maxsize;

    private static final int FRONT = 1;

    public MinHeap(int maxsize)
    {
        this.maxsize = maxsize;
        this.size = 0;
        NHeap = new Node[this.maxsize + 1];
    }

    private int parent(int pos)
    {
        return pos / 2;
    }

    private int leftChild(int pos)
    {
        return (2 * pos);
    }

    private int rightChild(int pos)
    {
        return (2 * pos) + 1;
    }

    private boolean isLeaf(int pos)
    {
        if (pos >=  (size / 2)  &&  pos <= size)
        { 
            return true;
        }
        return false;
    }

    private void swap(int fpos, int spos)
    {
        Node tmp;
        tmp = NHeap[fpos];
        NHeap[fpos] = NHeap[spos];
        NHeap[spos] = tmp;


    }

    private void minHeapify(int pos)
    {
        if (!isLeaf(pos))
        { 
            if ( NHeap[pos].getID() > NHeap[leftChild(pos)].getID()  || NHeap[pos].getID() > NHeap[rightChild(pos)].getID())
            {
                if (NHeap[leftChild(pos)].getID() < NHeap[rightChild(pos)].getID())
                {
                    swap(pos, leftChild(pos));
                    minHeapify(leftChild(pos));
                }else
                {
                    swap(pos, rightChild(pos));
                    minHeapify(rightChild(pos));
                }
            }
        }
    }

    public void insert(Node element)
    {
        NHeap[++size] = element;
        int current = size;

        while (NHeap[current].getID() < NHeap[parent(current)].getID())
        {
            swap(current,parent(current));
            current = parent(current);
        }   
    }
     public void first(Node element)
    {
        NHeap[0] = element; 
    }
    public void print()
    {
        for (int i = 1; i <= ((size/2)-1); i++ )
        {
            System.out.print(" PARENT : " + NHeap[i].getID() + " LEFT CHILD : " + NHeap[2*i].getID() 
                + " RIGHT CHILD :" + NHeap[2 * i  + 1].getID());
            System.out.println();
        } 
    }

    public void minHeap()
    {
        for (int pos = (size / 2); pos >= 1 ; pos--)
        {
            minHeapify(pos);
        }
    }

    public int remove()
    {
        int popped = NHeap[FRONT].getID();
        NHeap[FRONT] = NHeap[size--]; 
        minHeapify(FRONT);
        return popped;
    }
}

JavaApplication2.java:

package javaapplication2;
public class JavaApplication2 {
    public static void main(String[] args) {

        Node n = new Node();
        n.setID(5);
        Node n1 = new Node();
        n1.setID(45);
        Node n2 = new Node();
        n2.setID(17);
        Node n3 = new Node();
        n3.setID(10);
        Node n4 = new Node();
        n4.setID(84);
        Node n5 = new Node();
        n5.setID(19);
        Node n6 = new Node();
        n6.setID(6);
        Node n7 = new Node();
        n7.setID(22);
        Node n8 = new Node();
        n8.setID(9);


        System.out.println("The Min Heap is ");
        MinHeap minHeap = new MinHeap(15);
        minHeap.first(n);
        minHeap.insert(n1);
        minHeap.insert(n2);
        minHeap.insert(n3);
        minHeap.insert(n4);
        minHeap.insert(n5);
        minHeap.insert(n6);
        minHeap.insert(n7);
        minHeap.insert(n8);


        minHeap.print();
//        System.out.println("The Min val is " + minHeap.remove());
    }

}

Node.Java:

package javaapplication2;

public class Node {
        public int id;
    public int priority;
    public int timeSlice;

    public void setID(int newid){
        id = newid;
    }
    public int getID(){
        return id;
    }
}

1 个答案:

答案 0 :(得分:1)

您的insert功能存在错误。

public void insert(Node element)
{
    NHeap[++size] = element;
    int current = size;

    while (NHeap[current].getID() < NHeap[parent(current)].getID())
    {
        swap(current,parent(current));
        current = parent(current);
    }   
}

因为您的第一个节点位于索引1,所以每当节点向上移动到根时,这都会给您一个错误。此时,current将等于1,parent(current)将返回0.然后,您将比较根元素与NHeap[0]处的随机值。

您需要确保current大于1:

while (current > 1 && (NHeap[current].getId() < NHeap[parent(current)].getId())

minHeapify中也有错误。你有:

private void minHeapify(int pos)
{
    if (!isLeaf(pos))
    { 
        if ( NHeap[pos].getID() > NHeap[leftChild(pos)].getID()  || NHeap[pos].getID() > NHeap[rightChild(pos)].getID())
        {
            if (NHeap[leftChild(pos)].getID() < NHeap[rightChild(pos)].getID())
            {
                swap(pos, leftChild(pos));
                minHeapify(leftChild(pos));
            }else
            {
                swap(pos, rightChild(pos));
                minHeapify(rightChild(pos));
            }
        }
    }
}

但是如果NHeap[pos]没有正确的子节点,那么它将超出堆中的有效项目。你将在你的堆中获得随机的东西。

解决这个问题的方法是确定哪个孩子最小,考虑到可能没有合适孩子的可能性。然后将最小的孩子与父母进行比较:

if (isLeaf(pos)) return;

int leftChild = leftChild(pos);
int rightChild = rightChild(pos);

int smallestChild = leftChild;
if (rightChild <= size && NHeap[rightChild] < NHeap[leftChild])
{
    smallestChild = rightChild;
}
if (NHeap[pos] > NHeap[smallestChild])
{
    swap(pos, smallestChild);
    minHeapify(smallestChild);
}