Heap and heap sorting

Keywords: Java Algorithm

Hello, I'm Monday.

Today we talk about heap and heap sorting.

1, Pile

When it comes to heaps, we should first start with binary trees, from binary trees to complete binary trees, and then to heaps.

1. Binary tree

Each node can only have two subtrees at most, and can be divided into left and right

2. Complete binary tree

For a binary tree with n nodes with depth k, the nodes in the tree are numbered from top to bottom and from left to right. If the node numbered i (1 ≤ i ≤ n) is in the same position in the binary tree as the node numbered i in the full binary tree (except for the binary tree with no child nodes in the last layer, all nodes on each layer have two child nodes), Then this binary tree is called a complete binary tree.

The popular saying is that leaf nodes can only appear in the lowest and sub lower layers, and the leaf nodes in the lowest layer are concentrated on the left of the tree. It should be noted that a full binary tree must be a complete binary tree, and a complete binary tree is not necessarily a full binary tree.

For a node with position I, the left child (if any) 2i+1, the right child (if any) 2i+2, and the parent node (i-1)/2 (rounded down)

3. Pile

The first is a complete binary tree. Distinguish between large root heap and small root heap at the same time.

Large root heap: the maximum value of each subtree is the head node.

Small root heap: the minimum value of each subtree is the head node.

(1) How to construct a large root heap for an array of numbers entered by the user in turn?

Each inserted number is compared with the parent node. If it is greater than the parent node, it is exchanged with the parent node until the root node; If it is smaller than the parent node, the comparison is stopped immediately.

//  For the newly added number of i positions, please put it in the appropriate position of the array to make it a large root heap
private void heapInsert(int[] arr, int i) {
    //  i  =  0   or   I the number of locations is less than the parent node
    //  while contains these two termination conditions
    while(arr[i] > arr[(i - 1)/2]) {
        swap(arr, i, (i - 1)/2);
        i = (i - 1)/2;
    }
}

(2) Get the maximum value of the current array and delete it from the heap while maintaining the large root heap structure

public int pop() {
    int ans = heap[0];
    swap(heap, 0, --heapSize);
    heapify(heap, 0, heapSize);
    return ans;
}
//  Sink the number in the index position until the older children are not as old as themselves or have no children
private void heapify(int[] arr, int index, int heapSize) {
    //  Left subtree position
    int left = 2 * index + 1;
    while(left < heapSize) {        
        //  Find which of the left and right subtrees is more valuable
       int maxIndex = (left + 1) < heapSize && arr[left + 1] > arr[left] ? left + 1 : left;
       //  Compare the larger in the left and right subtrees with the parent node
       maxIndex = arr[maxIndex] > arr[index] ? maxIndex : index;
       //  The larger values of the left and right subtrees are less than the parent node. Stop the cycle      
       if (maxIndex == index) {
           break;
       }
       //  Swap the larger of the left and right subtrees with the parent node
       swap(arr, maxIndex, index);
       //  The node position of the current comparison comes to the larger child node
       index = maxIndex;
       //  Retrieve the left subtree of the current node
       left = 2 * index + 1;
    }
}

4,PriorityQueue

The bottom layer is implemented by heap, and the default is small root heap

5. Time complexity

heapinsert: add a number to the number that is already a heap structure. The time complexity is O(logN)

heapify, add a number to the number that is already a heap structure, and the time complexity is O(logN)

2, Heap sort

1. Adjust the entire array to a large root heap, and the number of positions 0 is the maximum

2. Exchange the number of 0 position and the maximum position of the array, and the maximum value is at the last ordered position

3. Reduce the number of adjustment ranges of the array by one, and cycle through steps 1 and 2 until the array is empty

public static void heapSort(int[] arr) {
    if (arr == null || arr.length < 2) {
        return;
    }
    //  Adjust the entire array to a large root heap, O(NlogN)
    for (int i = 0; i < arr.length; i++) { // O(N)
        heapinsert(arr, i); // O(logN)
    }
    //  Gets the current array size
    int heapSize = arr.length;
    //  The number of swap between the 0 position and the maximum position of the array
    swap(arr, 0, --heapSize);
    while(heapSize > 0) {
        //  Sink the number exchanged to position 0, that is, adjust the current array to a large root heap again
        heapify(arr, 0, heapSize);
        //  The number of swap between the 0 position and the maximum position of the array
        swap(arr, 0, --heapSize);
    }    
}

4. Complexity

(1) Time complexity: O(N*logN)

(2) Additional space complexity: O(1)

Posted by Rizla on Sun, 05 Dec 2021 16:02:42 -0800