Sorting algorithm-big root heap c++ && javascript implementation

Knowledge points

Heap: a complete binary tree;

Large root heap: all nodes except the root node, the value of the node is less than or equal to the parent node;
small root heap: all nodes except the root node, the value of the node is greater than or equal to the parent node;
heap sort: O(nlogn) , O(1), unstable;

Full binary tree: each node is a leaf node or a
perfect binary tree of degree 2 : a binary tree with a depth of k and the number of nodes is 2^k-1.
Complete binary tree: the number of the node corresponds to the number of the perfect binary tree.

Function description

  • heapify: Let the subtree of the current node meet the definition of the maximum heap or the minimum heap
  • swap: swap
  • build_heap: Build the heap, starting from the first non-leaf node and gradually traversing upwards, that is, each node traversed calls the heapify function
  • heap_sort: Realize heap sorting (big root heap), let the root node (index=0) exchange with the last node. At this time, the big root heap is not satisfied, so the last node (that is, the maximum value) is cut off and the root is re-run Heapify
function swap(tree, i, j){
    
    
    let temp = tree[i];
    tree[i] = tree[j];
    tree[j] = temp;
}
function heapify(tree, n, i){
    
    
    if (i >= n) return;
    let left = i*2 + 1;
    let right = i*2 + 2;
    let max = i;
    if (left < n && tree[left] > tree[max]){
    
    
        max = left;
    }
    if (right < n && tree[right] > tree[max]){
    
    
        max = right;
    }
    if (max !== i){
    
    
        swap(tree, max, i);
        heapify(tree, n, max);
    }
}

function build_heap(tree, n){
    
    
    let last_node = n-1;
    let parent = Math.floor((last_node - 1) / 2); // 注意向下取整
    for (let i = parent; i >= 0; i--){
    
    
        heapify(tree, n, i);
    }
}

function heap_sort(tree, n){
    
    
    build_heap(tree, n);
    for (let i=n-1; i>=0; i--){
    
    
        swap(tree, 0, i);
        heapify(tree, i, 0);
    }
}
let tree = [2,4,6,3,10,1,5];
heap_sort(tree, 7);
console.log(tree);
#include <iostream>
using namespace std;


void swap(int tree[], int i, int j){
    
    
    int temp = tree[i];
    tree[i] = tree[j];
    tree[j] = temp;
}
// 最大堆就是一个完全二叉树
// 当前节点i(i表示下标)的parent的index: (i-1)/2
// 当前节点i的left-child的index:i*2 + 1
// 当前节点i的right-child的index:i*2 + 2
void heapify(int tree[], int n, int i){
    
    
    // heapify就是从某个节点出发,让这个节点满足最大堆的定义
    if (i >= n) return;
    // n表示数组的长度,i表示当前的第几个元素
    int c1 = i*2 + 1;
    int c2 = i*2 + 2;
    int max = i;
    if (c1 < n && tree[c1] > tree[max]){
    
    
        max = c1;
    }
    if (c2 < n && tree[c2] > tree[max]){
    
    
        max = c2;
    }
    if (max != i){
    
    
        swap(tree, i, max); // 说明存在比tree[i]大的值
        heapify(tree, n, max);
    }
}

void build_heap(int tree[], int n){
    
     // 建立大根堆
    // 从第一个非叶子结点开始做heapify
    int last_node = n-1;
    int parent = (last_node - 1) / 2;
    for (int i=parent; i>=0; i--){
    
    
        heapify(tree, n, i);
    }
}
void heap_sort(int tree[], int n){
    
    
    build_heap(tree, n);
    for (int i=n-1; i>=0; i--){
    
     
        swap(tree, i, 0); 
        // 将第一个节点,也就是最大值与最后一个元素交换,然后把最后一个元素“砍断”,不进行heapify
        heapify(tree, i, 0); // O(logi)
    }
}
int main(){
    
    
    int tree[] = {
    
    2,4,6,3,10,1,5};
    // heapify(tree, 7, 0);
    heap_sort(tree, 7);
    for(int i=0; i<7; i++){
    
    
        cout << tree[i] << " ";
    }
    cout << endl;
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_42100456/article/details/115275123
Recommended