Java最小堆在删除元素后减少数组大小

时间:2018-11-06 12:40:11

标签: java arrays heap priority-queue heapsort

我正在创建具有最小堆排序的优先级队列(我自己以数组形式),在其中实现了一种方法,该方法删除优先级队列(我的数组)中的第一个元素即根。然后,我再次在数组上调用heapifyNumbers()方法,以最小堆中的数组再次排序。问题是我不能从数组中减少,所以最后两个元素将重复。

这是我正在创建的删除方法

public void deleteMinimum(int[] array){
    array[0] = array[array.length - 1];
    heapSort(array);
    //here I want to decrease array size by 1 after heap sorting the array
}

这里,我只是将第一个索引替换为最后一个索引,然后再次调用数组上的heapifyNumbers()方法以对数组进行排序。如何将数组大小减少1? 我知道数组不能减少,但是我看到了使用数组的所有实现,所以也许必须有某种方法像创建新数组一样?

这是我的输出:

  

在堆排序之前:
  [1、10、16、19、3、5]

     

堆后排序:
  [1、3、5、10、16、19]

     

删除后:

     

这里有重复的19

     

[3,5,10,16,19,19]

我已经完成了arr = Arrays.copyOf(array, array.length -1);,但是我不知道它是否仍然具有Log N时间复杂度

如果您有兴趣,这是我的完整代码:

import java.util.*;

public class ObligatoriskOpgave2 {
    int[] arr={1,10,16,19,3,5};

    public static void buildheap(int []arr) {

        /*
         * As last non leaf node will be at (arr.length-1)/2
         * so we will start from this location for heapifying the elements
         * */
        for(int i=(arr.length-1)/2; i>=0; i--){
            heapifyNumbers(arr,i,arr.length-1);
        }
    }

    public static void heapifyNumbers(int[] arr, int i, int size) {
        int left = 2*i+1;
        int right = 2*i+2;
        int max;
        if(left <= size && arr[left] > arr[i]){
            max=left;
        } else {
            max=i;
        }

        if(right <= size && arr[right] > arr[max]) {
            max=right;
        }
        // If max is not current node, swapCurrentNodeWithMaximumOfChildren it with max of left and right child
        if(max!=i) {
            swapCurrentNodeWithMaximumOfChildren(arr,i, max);
            heapifyNumbers(arr, max,size);
        }
    }

    public static void swapCurrentNodeWithMaximumOfChildren(int[] arr, int i, int j) {
        int t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }

    public static int[] heapSort(int[] arr) {

        buildheap(arr);
        int sizeOfHeap=arr.length-1;
        for(int i=sizeOfHeap; i>0; i--) {
            swapCurrentNodeWithMaximumOfChildren(arr,0, i);
            sizeOfHeap=sizeOfHeap-1;
            heapifyNumbers(arr, 0,sizeOfHeap);
        }
        return arr;
    }

    public void deleteMinimum(int[] array){
        array[0] = array[array.length - 1];
        heapSort(array);
    }

    public static void main(String[] args) {
        ObligatoriskOpgave2 o = new ObligatoriskOpgave2();

        System.out.println("Before Heap Sort : ");
        System.out.println(Arrays.toString(o.arr));
        o.arr=heapSort(o.arr);
        System.out.println("=====================");
        System.out.println("After Heap Sort : ");
        System.out.println(Arrays.toString(o.arr));


        o.deleteMinimum(o.arr);
        System.out.println(Arrays.toString(o.arr));
    }
}

2 个答案:

答案 0 :(得分:0)

https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html

  

数组是一个包含固定数量的单一类型值的容器对象。创建数组时将确定数组的长度。创建后,其长度是固定的。

因此,如果要使用数组,则必须使用新长度创建新数组。
并用旧数组的值填充新数组。 (请参阅第一个链接中的复制阵列部分)

答案 1 :(得分:0)

解决方案是使用HeapSize int值,每次删除元素时该值都会减小。下次在for循环中迭代数组时,我们所要做的仅是堆大小。