堆排序方法堆不起作用?

时间:2011-12-12 02:19:52

标签: java sorting

我真的一直把头发拉出来一段时间,并且会因此而死于某些答案。

我有一个基于数组的堆实现。插入时我的堆排序似乎正在工作,但是当我弹出顶部值时,我无法使下堆排序工作。我已经将完整的代码放在这里并且如果有人可以纠正downHeap方法以便在删除顶部值时能够对此数组进行排序,那么我会很喜欢它:

public class HeapSortArray {
static int sizeOfTree = 0; 

    private static int arrayBufferSize = 50;

    public static int[] heap = new int[arrayBufferSize];
    static int[] numbers = new int[]{ 0, 7, 9, 7, 5, 2, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };


    public static void main(String[] args) {
        insert(0);  //set 0 of the array to nothing

        //fill array with numbers
        for (int i = 1; i < numbers.length; i++) {

            insert(numbers[i]);
          if (i > 1) {
            upHeap(i);
          }
        }
        System.out.println("Heap Printed once inserted: ");
        for(int i=1; i < numbers.length; i++){
            System.out.println(heap[i]);
        }
        System.out.println("----------------------");
        System.out.println("Heap Printed as top value is popped out: ");
        //pop lowest value 
        for(int i = numbers.length; i != 1; i--){
             removeMin();
            }

    }




    public static void upHeap(int childLocation) {      

        int parentLocation = childLocation / 2;
        int child = childLocation;
        int parentTemp = heap[parentLocation];
        int childTemp = heap[childLocation];

        int parentValue = heap[parentLocation];
        int childValue =  heap[child];

        if (parentValue > childValue) {
            heap[parentLocation] = childTemp;
            heap[childLocation] = parentTemp;
        }
        if (parentLocation != 1) {
            upHeap(parentLocation);
        }
      }


    public static void downHeap(int location){

        if(location > 0){


            int parentLocation = location;
            int leftchildLocation = 2*location;
            int rightchildLocation = 2*location+1;


            int parentValue = heap[parentLocation];
            int leftchildValue = heap[leftchildLocation];
            int rightchildValue = heap[rightchildLocation];


            int parentTemp = heap[parentLocation];
            int leftChildTemp = heap[leftchildLocation];
            int rightChildTemp = heap[rightchildLocation];

            if(leftchildValue < rightchildValue && leftchildValue < parentValue){
                heap[parentLocation] =  leftchildValue;
                heap[leftchildLocation] = parentTemp;
                downHeap(leftchildLocation);
            }

            if(rightchildValue < leftchildValue && rightchildValue < parentValue){
                heap[parentLocation] =  rightchildValue;
                heap[rightchildLocation] = parentTemp;
                downHeap(rightchildLocation);
            }

        }

    }

    public static int removeMin() {

        sizeOfTree--;

        if(sizeOfTree > 1){
        heap[1] = heap[sizeOfTree];

        downHeap(1);
        }
        int toReturn = heap[1];
        System.out.println(toReturn);

        return toReturn;
    }

    public static void insert(int toInsert) {

        heap[sizeOfTree] = toInsert;    


    if(sizeOfTree > 1){
            upHeap(sizeOfTree);
            }


            sizeOfTree++;

        }

}

非常感谢任何能够对这一点有所了解的人。

编辑: 如果在第38行,上述实施将起作用:

int parentLocation = childLocation / 2;

更改为:

int parentLocation = childLocation -1;

我知道第二种方法不是它的意图,但为什么我的childLocation / 2没有给我父母呢?

1 个答案:

答案 0 :(得分:4)

以下是downHeap所需的检查:

  1. 位置必须在堆的大小范围内
  2. 正确的孩子是否在堆的大小范围内且是正确的孩子小于左子女和父母
  3. 否则,左边的子节点是堆的大小并且左边的子节点小于父节点

    public static void downHeap(int location){
    if(location < sizeOfTree){
        int p = location;
        int l = 2*p;
        int r = 2*p+1;
        int s = sizeOfTree;
        if(r<s && heap[r]<heap[p] && heap[r]<heap[l]){
            int temp = heap[r];
            heap[r] = heap[p];
            heap[p] = temp;
            downHeap(r);
        }else if(l<s && heap[l]<heap[p]){
            int temp = heap[l];
            heap[l] = heap[p];
            heap[p] = temp;
            downHeap(l);
        }
    }}
    
  4. 同样在removeMin()中,你应该在覆盖之前复制最小值:

        public static int removeMin() {
        sizeOfTree--;
        int toReturn = heap[1];
        if(sizeOfTree > 1){
            heap[1] = heap[sizeOfTree];
            downHeap(1);
        }
        System.out.println(toReturn);
        return toReturn;
    }