Large top pile and small top pile

Posted by jsucupira on Sat, 25 Dec 2021 23:10:21 +0100

Large top pile and small top pile

What is a heap

The essence of heap is a one-dimensional array maintained by the structure of complete binary tree.
According to the characteristics of the reactor, the reactor is divided into large top reactor and small top reactor
Large top heap: the value of each node is greater than or equal to the value of the left and right child nodes
Small top heap: the value of each node is less than or equal to the value of the left and right child nodes

Why heap

When we maintain the priority queue, if we use the ordinary sorting method, the time complexity is too high. We use heap to maintain an orderly structure that is updated at any time.
What we need is the minimum or maximum value in the heap. Through the heap structure, the time complexity of inserting or extracting values is low enough. Because it is divided into arbitrary subsets, and then subsets are divided continuously, its search and insertion efficiency is high.

Characteristics of reactor

Memory occupation: ordinary trees occupy a large memory space, because we must allocate memory for nodes and left and right pointers. However, the heap is saved in an array, so the memory occupation of the heap structure is small.
Time complexity: the time complexity in the heap can reach On*log(2n).
Search speed: the search speed of the heap is very slow, because the purpose of the heap is to put the largest (smallest) node in front, so as to quickly insert and delete

Large top heap sorting process

1. Give an array

let a = [7,3,8,5,1,2]

2. Construct binary tree

Now we need to turn this sequence into our heap.

  • Ascending order: large top reactor
    +The value of each node is greater than that of the left and right child nodes. The value of the root node is the largest. Then exchange the position between the root node and the last node, and the end is the largest element.
  • Descending order: small top reactor

Process of constructing large top pile

  • 1. Find the last non leaf node. The index of the last non leaf node is: arr.length/2 + 1, that is, 6 / 2 + 1 = 2. Then compare the value of the node with its child nodes. If the node is smaller than the child tree, exchange it.

  • 2. Find the next non leaf node, which is actually the current coordinate - 1. Here is node 1. Ensure that the value of node 1 is greater than that of the child node.

  • 3. Find the next non leaf node and ensure that the value of this node is greater than that of the child node

Constructing priority queue through large top heap

  • How to get the parent node index of each node: ~ ~ ((index-1) / 2)
  • Bitwise operator ~ ~: you can use a bitwise operator to replace the math of a positive number Floor(), replacing math. For negative numbers ceil( ). The advantage of the double no positioning operator is that it performs the same operation faster.
// First, define a class that requires methods for joining and leaving the queue
class PriorityQueue{
	// When new, arr can be passed in
    constructor(arr){
        if (arr.length){
            // Constructing a heap from an array
            this.tree = []
            this._build_tree(arr);
            return;
        }
        this.tree = [];
    }

    // Join the team
    enqueue(val){
        // Put the value in the last bit of the array tree
        // Put the value directly on the leaf node, and then perform the floating operation
        this.tree.push(val);
        // this.tree.length-1 is the index of the value put in
        this._up(this.tree.length - 1);
    }

    // Out of the team
    dequeue(){
        // Take tree root element
        this.tree.shift();
        // Put the last element in the root position and sink
        let last = this.tree.pop();
        this.tree.unshift(last);
        // log(n) sink
        this._down(0);
    }

    // Take the value of team leader
    getFirst(){
        return this.tree[0];
    }

    _build_tree(arr){
        let tree = this.tree;
        tree.push(arr[0]);
        for (let i = 1; i < arr.length; i++){
            // Put the element in the root position
            tree.unshift(arr[i]);
            // Sink element 0
            this._down(0);
        }
    }
}

Implementation of sinking code

  • 1. First, you need to get the last node that is not a leaf node
  • 2. Maintain the value of the node so that the value of the node is greater than that of the child node
    _down(index){
        let tree = this.tree;
        // Gets the index of the last node that is not a leaf node
        let last_no_leaf = ~~((tree.length - 2) / 2);
        // index is the leaf node, which is already at the bottom. There is no need to sink
        if (index > last_no_leaf) return;
        // If index is not a leaf node
        while(index <= last_no_leaf){
            let l = tree[index * 2 + 1];
            let r = tree[index * 2 + 2] || tree[index * 2 + 1]; // There may be no right son
            // Get the maximum value in the left and right child nodes
            let max = l >= r ? l : r;
            let maxIndex = l >= r ? index * 2 + 1: index * 2 + 2
            if (tree[index] < max){
                // Exchange with maximum
                [tree[index], tree[maxIndex]] = [tree[maxIndex], tree[index]]
                // When the corresponding value reaches the MaxIndex position, continue to sink it
                index = maxIndex;
            }else{
                return;
            }
        }
    }

Implementation of floating code

    _up(index){
        let tree = this.tree;
        // This value does not reach the root node
        while(index !== 0){
            // Parent node found
            let p = ~~((index - 1) / 2);
            // If it is larger than the parent node, it will be swapped, and then continue to compare with the previous node
            if (tree[index] > tree[p]){
                [tree[index], tree[p]] = [tree[p], tree[index]];
                // let tmp = index;
                // this._down(tmp);
                index = p;
            } else {
                return;
            }
        }
    }

Topics: data structure