堆 04 替换堆顶元素 & 堆化

Replace - 取出堆中最大的元素,并替换成新元素 O(logn)

  • 找出堆顶元素(即取出数组中索引为0的元素);
  • 用新元素替换堆顶元素(用新元素替换数组中索引为0的元素);
  • 下沉新放入堆顶的元素;
  • 返回最开始取出的堆顶元素;
// 取出堆中的最大元素,并且替换成元素e
public E replace(E e){
    E ret = findMax();
    data.set(0, e);
    siftDown(0);
    return ret;
}

Heapify - 将任意数组整理成堆的结构 O(n)

  • 从最后一个非叶子节点开始下沉;
  • 最后一个非叶子节点的索引:parent(arr.length - 1);
public MaxHeap(E[] arr){
    data = new Array<>(arr);
    for(int i = parent(arr.length - 1) ; i >= 0 ; i --)
        siftDown(i);
}

测试代码

public class Main {

    private static double testHeap(Integer[] testData, boolean isHeapify){
        long startTime = System.nanoTime();

        MaxHeap maxHeap;
        if(isHeapify)
            maxHeap = new MaxHeap<>(testData);
        else{
            maxHeap = new MaxHeap<>();
            for(int num: testData)
                maxHeap.add(num);
        }

        int[] arr = new int[testData.length];
        for(int i = 0 ; i < testData.length ; i ++)
            arr[i] = maxHeap.extractMax();

        for(int i = 1 ; i < testData.length ; i ++)
            if(arr[i-1] < arr[i])
                throw new IllegalArgumentException("Error");
        System.out.println("Test MaxHeap completed.");

        long endTime = System.nanoTime();
        return (endTime - startTime) / 1000000000.0;
    }

    public static void main(String[] args) {
        int n = 1000000;

        Random random = new Random();
        Integer[] testData = new Integer[n];
        for(int i = 0 ; i < n ; i ++)
            testData[i] = random.nextInt(Integer.MAX_VALUE);

        double time1 = testHeap(testData, false);
        System.out.println("Without heapify: " + time1 + " s");

        double time2 = testHeap(testData, true);
        System.out.println("With heapify: " + time2 + " s");
    }

}

输出:

Test MaxHeap completed.
Without heapify: 1.0694262 s
Test MaxHeap completed.
With heapify: 0.8363691 s

你可能感兴趣的:(堆 04 替换堆顶元素 & 堆化)