DAILY DOCDAILY DOC
Rust
Node
Notes
Ubuntu
Leetcode
  • it-tools
  • excalidraw
  • linux-command
Rust
Node
Notes
Ubuntu
Leetcode
  • it-tools
  • excalidraw
  • linux-command
  • Array

    • 数组
    • 二分查找
    • moveZeros
  • Dynamic-programming

    • 动态规划
  • 刷题指南
  • String

    • 字符串
  • bitwise-operator

    • 位运算符
  • heap
  • history

    • [1014] 最佳观光组合
    • [1022] 从根到叶的二进制数之和
    • [104] 二叉树的最大深度
    • [11] 盛最多水的容器
    • [110] 平衡二叉树
    • [1227] 飞机座位分配概率
    • [129] 求根节点到叶节点数字之和
    • [1306] 跳跃游戏 III
    • [148] 排序链表
    • 155.最小栈
    • [165] 比较版本号
    • 1763. 最长的美好子字符串
    • [1870] 准时到达的列车最小时速
    • [199] 二叉树的右视图
    • [21] 合并两个有序链表
    • 215.数组中的第 k 个最大元素
    • [2306] 公司命名
    • [234] 回文链表
    • [2516] 每种字符至少取 K 个
    • [316] 去除重复字母
    • [3171] 找到按位或最接近 K 的子数组
    • [322] 零钱兑换
    • [41] 缺失的第一个正数
    • [44] 通配符匹配
    • [494] 目标和
    • [509] 斐波那契数
    • [518] 零钱兑换 II
    • [62] 不同路径
    • [676] 实现一个魔法字典
    • 70 爬楼梯
    • [718] 最长重复子数组
    • [78] 子集
    • [82] 删除排序链表中的重复元素 II
    • [871] 最低加油次数
    • [88] 合并两个有序数组
    • [887] 鸡蛋掉落
    • 958.二叉树的完全性检验
    • [98] 验证二叉搜索树
    • [983] 最低票价
    • leetcode practice
    • 约瑟夫问题
    • 移除重复节点
  • linked-list

    • 706. 设计哈希映射
    • 链表
  • stack

    • stack
  • tree

    • Tree Traversal
    • 二叉树的最近公共祖先
    • 二叉树
    • 题目
  • leetCode 刷题
  • 回溯
  • 排序算法

heap

details
class Heap {
    constructor() {
        this.data = [];
    }
    parentIndex(index) {
        return ((index - 1) / 2) >> 0;
    }
    leftIndex(i) {
        return 2 * i + 1;
    }
    rightIndex(i) {
        return 2 * i + 2;
    }
    swap(i, j) {
        [this.data[i], this.data[j]] = [this.data[j], this.data[i]];
    }
    size() {
        return this.data.length;
    }
    insert(val) {
        this.data.push(val);
        this.heapifyUp();
    }
    peek() {
        return this.data.at(0);
    }
    heapifyUp() {
        let i = this.size() - 1;
        let pIndex = this.parentIndex(i);
        while (pIndex >= 0 && this.data[i] > this.data[pIndex]) {
            this.swap(i, pIndex);
            i = pIndex;
            pIndex = this.parentIndex(i);
        }
    }
    remove() {
        if (this.size() === 0) return null;
        if (this.size() === 1) return this.data.shift();
        const root = this.data.at(0);
        this.data[0] = this.data.pop();
        this.heapifyDown();
        return root;
    }
    heapifyDown() {
        let i = 0;
        while (this.leftIndex(i) < this.size()) {
            let maxIndex = this.leftIndex(i);
            if (this.rightIndex(i) < this.size() && this.data[this.rightIndex(i)] > this.data[maxIndex]) {
                maxIndex = this.rightIndex(i);
            }

            if (this.data[i] < this.data[maxIndex]) {
                this.swap(i, maxIndex);
                i = maxIndex;
            } else {
                break;
            }
        }
    }
}

// 测试用例
const maxHeap = new Heap();
maxHeap.insert(3);
maxHeap.insert(10);
maxHeap.insert(5);
maxHeap.insert(6);
maxHeap.insert(7);

console.log('Max value (extract):', maxHeap.remove()); // 10
console.log('Current max (peek):', maxHeap.peek()); // 7
console.log('Max value (extract):', maxHeap.remove()); // 7

构建最大堆

details
function buildMaxHeap(arr) {
    // 从最后一个非叶子节点开始
    let parentIndex = ((arr.length - 2) / 2) >> 0;
    while (parentIndex >= 0) {
        maxHeapify(arr, parentIndex, arr.length);
        parentIndex--;
    }
}

function maxHeapify(arr, index, heapSize) {
    let left = 2 * index + 1; // 左子节点
    let right = 2 * index + 2; // 右子节点
    let largest = index; // 初始化最大元素为当前节点

    // 如果左子节点比当前节点大,则更新最大元素为左子节点
    if (left < heapSize && arr[left] > arr[largest]) {
        largest = left;
    }

    //  如果右子节点比最大元素大,则更新最大元素为右子节点
    if (right < heapSize && arr[right] > arr[largest]) {
        largest = right;
    }

    // 如果最大元素不是当前节点,则交换当前节点和最大元素的位置,并递归地对交换后的子树进行堆化
    if (largest !== index) {
        [arr[index], arr[largest]] = [arr[largest], arr[index]];
        // 递归地对受影响的子树进行最大堆化
        maxHeapify(arr, largest, heapSize);
    }
}
Last Updated:
Contributors: rosendo