0004 : 算法——堆排序

127 阅读1分钟

算法

堆排序使用数据结构的特点进行排序

注意:堆一个树叶向下的树形结构,根节点永远是最小的,root<左子&root<右子

时间复杂度

入堆时间复杂度:O(nlogn)O(nlogn)

出堆时间复杂度:O(nlogn)O(nlogn)

整体时间复杂度:O(nlogn)O(nlogn)

js

const input = [4,2,15,2,5,6,21,67,2,3]

const heapAdd = (roots, val) => {
    const childs = [];
    let node = null;
    const notadded = roots.every(root => {
        if (!root.left) {
            root.left = {
                val,
                parent: root,
            }
            node = root.left
            return false;
        }
        if (!root.right) {
            root.right = {
                val,
                parent: root,
            }
            node = root.right
            return false;
        }
        childs.push(root.left)
        childs.push(root.right)
        return true
    })
    if (notadded) {
        return heapAdd(childs, val)
    }
    return node
}

const heapSort = (node) => {
    if (!node.parent) return;
    if (node.val < node.parent.val) {
        const temp = node.parent.val
        node.parent.val = node.val
        node.val = temp
        heapSort(node.parent)
    }
}

const heapDown = (root) => {
    if (!root) return;
    const right = root.right;
    let node = root.left;
    if (right && node && right.val < node.val) {
        node = right;
    }
    if (node && node.val < root.val) {
        const temp = node.val
        node.val = root.val
        root.val = temp
        heapDown(node)
    }
    
}

const getRight = (root) => {
    if (!root) return root;
    if (!root.left && !root.right) return root
    if (root.right) return getRight(root.right);
    return getRight(root.left)
}

const heapPop = (root) => {
    const temp = root.val;
    const left = root.left;
    const right = root.right;
    if (!left && !right) return temp;
    const final = getRight(root);
    if (final) {
        root.val = final.val
        const finalParent = final.parent
        if (finalParent && finalParent.right === final) {
            finalParent.right = null;
        } else if (finalParent && finalParent.left === final) {
            finalParent.left = null;
        }

        heapDown(root)
        return temp
    }
    return temp;
}

const sort = (arr) => {
    const root = { val : arr[0]}
    for(let i = 1; i < arr.length; i++) {
       const node = heapAdd([root], arr[i]) 
       heapSort(node)
       final = node;
    }
    for (let i = 0; i < arr.length; i++) {
        arr[i] = heapPop(root);
    }
    return arr;
}
console.log(sort(input))