美文网首页
JavaScript - 排序算法 - 堆排序

JavaScript - 排序算法 - 堆排序

作者: ElricTang | 来源:发表于2020-10-22 14:14 被阅读0次

    特点:

    • 时间复杂度:O(nlog2n)
    • 堆排序是不稳定的排序算法

    原理:

    • 利用大顶堆排序(升序)
    • 利用小顶堆排序(降序)
    • 初始时将待排序数组生成堆结构
    • 将堆顶换到堆尾,并取出放入结果集
    • 重新维护堆结构,获取下一个堆顶,重复上述操作
    • 当堆被清空,排序完成

    代码实现:

    • 堆排序的核心在于维护堆结构,并实现一个重置堆的方法(heapify)。
      1. 使用数组存储堆结构(使用树结构同样可以,但是浪费空间)
        重要性质:节点关系与数组index的映射关系
    parent(i) = floor((i - 1)/2)
    left(i)   = 2i + 1
    right(i)  = 2i + 2
    
    // 数据结构-最大堆
    let heap = [];
    
    // utils,交换位置
    function swap(index1, index2) {
        [heap[index1], heap[index2]] = [heap[index2], heap[index1]];
    }
    
    // 上浮shiftUp,维护堆的属性
    function shiftUp(index) {
        let fatherIndex = Math.floor((index - 1) / 2);
    
        if (index !== 0 && heap[fatherIndex] < heap[index]) {
            swap(fatherIndex, index);
            shiftUp(fatherIndex);
        }
    }
    
    // 下沉shiftDown,也被称为堆化
    function shiftDown(index) {
        // 判断是否比子节点小
        let leftChild = index * 2 + 1;
        let rightChild = index * 2 + 2;
    
        if (leftChild < heap.length && heap[index] < heap[leftChild]) {
            swap(index, leftChild);
            shiftDown(leftChild);
        }
        if (rightChild < heap.length && heap[index] < heap[rightChild]) {
            swap(index, rightChild);
            shiftDown(rightChild);
        }
    }
    
    function heapSort(arr) {
        // 建堆
        for (let i of arr) {
            heap.push(i);
            shiftUp(heap.length - 1);
        }
        let res = [];
    
        while (heap.length > 0) {
            swap(0, heap.length - 1);
            res.push(heap.pop());
            shiftDown(0);
        }
        return res;
    }
    

    相关文章

      网友评论

          本文标题:JavaScript - 排序算法 - 堆排序

          本文链接:https://www.haomeiwen.com/subject/idwumktx.html