用户已经创建了 Heap 后,如何使用 HeapSort 方法?

Posted

技术标签:

【中文标题】用户已经创建了 Heap 后,如何使用 HeapSort 方法?【英文标题】:How do I use the HeapSort Method after the user has already created the Heap? 【发布时间】:2016-03-14 07:35:30 【问题描述】:

大家好,我正在为我的编程课做一个实验作业,我们必须创建一个堆,用户将整数输入到数组中然后显示它,然后我们假设使用这些相同的值并很好地使用 HeapSort第一部分相当简单,我每次尝试调用 HeapSort 方法来对数组进行排序时遇到了问题,我遇到了这个错误

线程“main”中的异常 java.lang.NullPointerException at HeapApp.heapSort(HeapApp.java:11) 在 HeapApp.main(HeapApp.java:88)

错误特别指出

int count = hp.length; 

HeapApp.heapSort(HP);

请帮忙!这是我这门课的最后一项作业!

堆类

import java.util.ArrayList;
import java.util.NoSuchElementException;


public class Heap<T extends Comparable<T>> 

private  ArrayList<T> items;


public Heap() 
    items = new ArrayList<T>();


private void siftUp() 
    int k = items.size() - 1;
    while (k > 0) 
        int p = (k-1)/2;
        T item = items.get(k);
        T parent = items.get(p);
        if (item.compareTo(parent) > 0) 
            // swap
            items.set(k, parent);
            items.set(p, item);

            // move up one level
            k = p;
         else 
            break;
        
    


public void insert(T item) 
    items.add(item);
    siftUp();


private void siftDown() 
    int k = 0;
    int l = 2*k+1;
    while (l < items.size()) 
        int max=l, r=l+1;
        if (r < items.size())  // there is a right child
            if (items.get(r).compareTo(items.get(l)) > 0) 
                max++;
            
        
        if (items.get(k).compareTo(items.get(max)) < 0) 
                // switch
                T temp = items.get(k);
                items.set(k, items.get(max));
                items.set(max, temp);
                k = max;
                l = 2*k+1;
         else 
            break;
        
    


public T delete() 
throws NoSuchElementException 
    if (items.size() == 0) 
        throw new NoSuchElementException();
    
    if (items.size() == 1) 
        return items.remove(0);
    
    T hold = items.get(0);
    items.set(0, items.remove(items.size()-1));
    siftDown();
    return hold;


public int size() 
    return items.size();


public boolean isEmpty() 
    return items.isEmpty();



public String toString() 
    return items.toString();





import java.util.Scanner;


public class HeapApp 



/**
 * @param args
 */
public static void main(String[] args) 
    Heap<Integer> hp = new Heap<Integer>();


    Scanner sc = new Scanner(System.in);
    HeapApp HP = new HeapApp();
    System.out.print("Enter next int, 'done' to stop: ");
    String line = sc.next();

    while (!line.equals("done")) 
        hp.insert(Integer.parseInt(line));
        System.out.println(hp);
        System.out.print("Enter next int, 'done' to stop: ");
        line = sc.next();
    

    while (hp.isEmpty()) 
        //int max = hp.delete();
        System.out.println(hp);
    


    System.out.println(hp);
    HP.heapSort(HP);
    System.out.println("After sorting " + hp);

 




private static int [] hp;



public static void heapSort(HeapApp HP)
        int count = hp.length;

        //first place a in max-heap order
        heapify(hp, count);

        int end = count - 1;
        while(end > 0)
            //swap the root(maximum value) of the heap with the
            //last element of the heap
            int tmp = hp[end];
            hp[end] = hp[0];
            hp[0] = tmp;
            //put the heap back in max-heap order
            siftDown(hp, 0, end - 1);
            //decrement the size of the heap so that the previous
            //max value will stay in its proper place
            end--;
        
    

    public static void heapify(int[] hp, int count)
        //start is assigned the index in a of the last parent node
        int start = (count - 2) / 2; //binary heap

        while(start >= 0)
            //sift down the node at index start to the proper place
            //such that all nodes below the start index are in heap
            //order
            siftDown(hp, start, count - 1);
            start--;
        
        //after sifting down the root all nodes/elements are in heap order
    

    public static void siftDown(int[] hp, int start, int end)
        //end represents the limit of how far down the heap to sift
        int root = start;

        while((root * 2 + 1) <= end)      //While the root has at least one child
            int child = root * 2 + 1;           //root*2+1 points to the left child
            //if the child has a sibling and the child's value is less than its sibling's...
            if(child + 1 <= end && hp[child] < hp[child + 1])
                child = child + 1;           //... then point to the right child instead
            if(hp[root] < hp[child])     //out of max-heap order
                int tmp = hp[root];
                hp[root] = hp[child];
                hp[child] = tmp;
                root = child;                //repeat to continue sifting down the child now
            else
                return;
        
    


【问题讨论】:

请通过选择代码并单击代码按钮来修复您的格式。还要说明异常来自哪一行。 【参考方案1】:
  private static int [] hp; is null 

在访问此行之前验证您是否初始化了 hp 数组

   int count = hp.length;

请参考链接

How do I declare and initialize an array in Java?

How to initialize an array in Java?

如果你想使用动态数组,请参考这里

how to use an array list?

【讨论】:

请举例说明您的意思【参考方案2】:

这是一个堆排序的示例程序。该示例将 int [] 作为堆排序的输入。调用doHeapSort方法,传入int[]

public static void doHeapSort(int [] inputArray)

    for(int i = 0; i < inputArray.length; i++)
    
        keepMaxHeapFindingParentElement(i, inputArray);
    
    sortAndMaintainHeap(inputArray, inputArray.length - 1);



private static void sortAndMaintainHeap(int [] inputArray, int lastElementIndex)

    if(lastElementIndex <= 0)
    
        return;
    
    swap(inputArray, 0, lastElementIndex);
    lastElementIndex--;
    keepMaxHeapFindingChildElement(inputArray, 0, lastElementIndex);
    sortAndMaintainHeap(inputArray, lastElementIndex);


private static void keepMaxHeapFindingChildElement(int [] inputHeap, int currentElementIndex, int lastElementIndex)

    if(currentElementIndex >= lastElementIndex)
    
        //no more child node
        return;
    
    int child1Index = 2*currentElementIndex + 1;
    int child2Index = 2*currentElementIndex + 2;
    int childIndex = 0;
    if(child2Index <= lastElementIndex)
    
        childIndex = inputHeap[child1Index] > inputHeap[child2Index] ? child1Index : child2Index;
    
    else if(child1Index <= lastElementIndex)
    
        childIndex = child1Index;
    
    else
    
        return;
    
    if(inputHeap[currentElementIndex] < inputHeap[childIndex])
    
        swap(inputHeap, currentElementIndex, childIndex);
        keepMaxHeapFindingChildElement(inputHeap, childIndex, lastElementIndex);
    
    else
    
        return;
    


private static void keepMaxHeapFindingParentElement(int elementIndex, int [] inputHeap)

    if(elementIndex == 0)
    
        // no more parent node
        return;
    
    int parentElementIndex = (elementIndex - 1)/2;
    if(inputHeap[elementIndex] > inputHeap[parentElementIndex])
    
        //swap child and parent
        swap(inputHeap, elementIndex, parentElementIndex);
        keepMaxHeapFindingParentElement(parentElementIndex, inputHeap);
    

【讨论】:

以上是关于用户已经创建了 Heap 后,如何使用 HeapSort 方法?的主要内容,如果未能解决你的问题,请参考以下文章

[CF538F]A Heap of Heaps(主席树)

1147 Heaps

PAT甲级——1147 Heaps30

1147 Heaps (30分)

PAT Advanced 1147 Heaps (30分)

容器适配器————heap