Priority queue (heap)

Table of contents

1. The concept of heap

2. Heap storage structure

3. Implementation of heap

3.1 shiftDown()

3.2 shiftUp()

3.3 Time complexity of shiftDown and shiftUp

4. Heap sort


1. The concept of heap

Heaps are often used to implement applications such as Priority Queues, where elements with the highest (or lowest) priority can be quickly found and deleted. Heap operations include inserting new elements, removing the top element in the heap (i.e., the highest value), and adjusting existing heaps to satisfy the heap-order property. Common heap adjustment operations are "float" (up filter) and "sink" (down filter) .

The heap has the following two main characteristics:

  1.  The heap is a complete binary tree
  2.  The value of each node in the heap must be greater than or equal to (or less than or equal to) the value of its child node.

2. Heap storage structure

From the concept of heap, we can know that the heap is a complete binary tree in its logical structure, so it can be stored efficiently in a sequential manner according to the rules of hierarchical order. In other words, the heap is stored using a sequence table. Draw a picture to understand:

 After storing the elements into an array, the tree can be restored according to the properties of a complete binary tree. Assuming i is the subscript of the node in the array, then:

  • If i = 0, then the node represented by i is the root node, otherwise the parent node of node i is (i - 1)/2
  • If 2 * i + 1 is less than the number of nodes, the left child subscript of node i is 2 * i + 1, otherwise there is no left child
  • If 2 * i + 2 is less than the number of nodes, the right child index of node i is 2 * i + 2, otherwise there is no right child

3. Implementation of heap

What is implemented here is a large root heap:

public class Heap {
    private int[] elem;
    private int usedSize;

    public Heap(int[] arr){
        elem = new int[arr.length];
        createHeap(arr);
    }

    //建堆
    public void createHeap(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            elem[i] = arr[i];
            usedSize++;
        }
        for (int parent = (usedSize-2)/2; parent >= 0; parent--) {
            shiftDown(parent,usedSize);
        }
    }

    //向下调整
    public void shiftDown(int parent, int len){}

    public void swap(int i, int j){
        int tmp = elem[i];
        elem[i] = elem[j];
        elem[j] = tmp;
    }

    //入堆
    public void push(int val){}

    public boolean isFull(){
        return usedSize == elem.length;
    }

    //向上调整
    public void shiftUp(int child){}

    //出堆顶元素
    public int poll(){
        if(isEmpty()){
            System.out.println("堆中没有元素");
            return -1;
        }
        swap(0,usedSize-1);//将头尾交换
        usedSize--;//去掉堆顶元素
        shiftDown(0,usedSize);//重新排序
        return elem[usedSize];//返回堆顶元素
    }

    public boolean isEmpty(){
        return usedSize == 0;
    }

    //得到堆顶元素
    public int peek(){
        if(!isEmpty()){
            return elem[0];
        }
        System.out.println("堆中没有元素");
        return -1;
    }
}

The core code in the heap is the implementation of the shiftDown() and shiftUp() methods . You can understand the other methods by looking at them. Let’s talk about the implementation of these two methods in detail.

3.1 shiftDown()

For example, we want to turn the array {27, 15, 19, 18, 28, 34, 65, 49, 25, 37} into a heap. How do we implement it? The idea: first find the last subtree and turn it into a heap. After forming a pile, traverse other subtrees in sequence until the root node of the last subtree is the root node of the entire tree . See the figure below: 

code show as below:

    public void shiftDown(int parent, int len){
        int child = 2*parent + 1;
        while(child < len){
            if(child+1 < len && elem[child] < elem[child+1]){
                child++;
            }
            if(elem[parent] < elem[child]){
                swap(parent,child);
                parent = child;
                child = 2*parent + 1;
            }else{
                break;
            }
        }
    }

3.2 shiftUp()

This method is to insert an element in the form of a heap when inserting it. Essentially, the ideas of shiftDown and shiftUp are similar:

    public void shiftUp(int child){
        int parent = (child-1)/2;
        while(parent >= 0){
            if(elem[child] > elem[parent]){
                swap(child,parent);
                child = parent;
                parent = (child-1)/2;
            }else {
                break;
            }
        }
    }

3.3 Time complexity of shiftDown and shiftUp

 ​​​​​​​​​​​​​​

 

4. Heap sort

For example, if we want to sort in ascending order, we first need to create a large root heap, and then exchange the root node with the last node. At this time, the last node must be the largest, then perform shiftDown, and then exchange the root node with the penultimate node. exchange, and so on. code show as below:

/**
     * 堆排序
     * 时间复杂度:O(N*logN)
     * 空间复杂度:O(1)
     * 不稳定
     */
    public void heapSort(int[] arr){
        createHeap(arr);
        int end = arr.length-1;
        while(end > 0){
            swap(arr,0,end);
            shiftDown(arr,0,end);
            end--;
        }
    }
    private void shiftDown(int[] arr, int parent,int len) {
        int child = 2*parent+1;
        while(child < len){
            if(child+1 < len && arr[child] < arr[child+1]){
                child++;
            }
            if(arr[child] > arr[parent]){
                swap(arr,child,parent);
                parent = child;
                child = 2*parent+1;
            }else{
                break;
            }
        }
    }
    public void swap(int[] arr, int i, int j){
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
    public void createHeap(int[] array) {
        for (int parent = (array.length-2)/2; parent >= 0; parent--) {
            shiftDown(array,parent,array.length);
        }
    }

Guess you like

Origin blog.csdn.net/m0_74859835/article/details/132024358