Implementation of large/small root heap in Java

Using an algorithm to illustrate the problem using the heap scenes
leetecode-215

Introduction to the heap

Small root pile: the value of the parent node is less than or equal to the value of the child node
Large root pile: the value of the parent node is greater than or equal to the value of the child node
Insert picture description here

Heap storage

This is particularly worth mentioning, because it is related to the subsequent implementation. Generally, it is stored in an array. The priority queue in Java is stored in an Object[] array; although the heap is a complete binary tree, it is generally not stored in a tree structure, precisely because it is a complete binary tree, which has many special properties. It happens to be stored in an array.
The most critical properties here are:

1) The subscript of the parent node of node i is (i–1)/2;
2) The subscripts of the left and right child nodes of node i are 2 * i + 1 and 2 * i + 2 respectively
Insert picture description here

Heap operation

Insert: Insert at the end of the heap, and then adjust from bottom to top; adjust it once to become orderly, and the time complexity is o(logn)

private static void siftUp(int[] heap, int i) {
    
    
    if (i <= 0) return;
    // 父节点
    int parent = (i - 1) / 2;
    if (heap[parent] > heap[i]) {
    
    
        int t = heap[i];
        heap[i] = heap[parent];
        heap[parent] = t;
        siftUp(heap, parent); // 递归往上
    }
}

Delete: Generally pop up the top element of the heap, then replace the top element with the last element, and then adjust downwards. The time complexity is also o(logn)

    private static void siftDown(int[] heap, int i) {
    
    
        // 写一个递归的方式
        int left = i * 2 + 1;
        int right = i * 2 + 2;
        int minIndex = getMinIndex(heap, i, left, right);
        if (minIndex != i) {
    
    
            int tem = heap[i];
            heap[i] = heap[minIndex];
            heap[minIndex] = tem;
            // 递归调整子节点
            siftDown(heap, minIndex);
        }
    }
    private static int getMinIndex(int[] heap, int i, int left, int right) {
    
    
        int minIndex = i;
        if (left < size && heap[left] < heap[i]) {
    
    
            minIndex = left;
        }
        if (right < size && heap[right] < heap[minIndex]) {
    
    
            minIndex = right;
        }
        return minIndex;
    }

Implementation of the heap

Adjustment heap/construction heap
Start adjustment from i = n/2-1 node, after which all are leaf nodes

    private static void heapIfy(int[] heap) {
    
    
        // 最后一个非叶子节点开始调整
        int i = size / 2 - 1;
        for (; i >= 0; i--) {
    
    
            siftDown(heap, i);
        }
    }

to sum up

The structure of piles seems scary, but it feels very rare. But if you really understand it, you will find that it is very well implemented. It essentially has only two operations:
1) Adjust downwards and
2) Adjust upwards.
In addition, these two operations have non-recursive implementations. If you are interested, you can think about and implement them.

Guess you like

Origin blog.csdn.net/weixin_42541360/article/details/114478453