数据结构---堆

一;什么是堆?

堆是一种特殊的完全二叉树,所有的节点都大于等于(最大堆)或小于等于(最小堆)它的子节点

二;JS中的堆

1.JS中通常用数组表示堆。

2.左侧子节点的位置是 2 * index + 1

3.右侧子节点的位置是 2 * index + 2

4.父节点的位置是(index - 1)/ 2

三;堆的应用

堆能高效、快速的找出最大值和最小值,时间复杂度为O(1);

找出第 K 个最大(小)元素

 四;JS实现堆的基本操作(入堆,删除堆顶,堆长度,取堆尾)

class MinHeap {
    constructor() {
        this.heap = [];
    }
    // 交换父节点与子节点
    swap(i1, i2) {
        const temp = this.heap[i1];
        this.heap[i1] = this.heap[i2];
        this.heap[i2] = temp;
    }
    // 获取当前节点的父节点
    getParentIndex(i) {
        return Math.floor((i - 1) / 2);
    }
    getLeftIndex(i) {
        return i * 2 + 1;
    }
    getRightIndex(i) {
        return i * 2 + 2;
    }
    // 向堆尾添加元素需要进行上移操作
    // 上移操作,比较父节点与子节点的大小,若父节点比子节点大,则交换俩节点
    // 目的是让新加入的节点符合堆的数据结构
    shiftUp(index) {
        if (index == 0) return;
        const parentIndex = this.getParentIndex(index);
        if (this.heap[parentIndex] > this.heap[index]) {
            this.swap(parentIndex, index);
            this.shiftUp(parentIndex);
        }
    }
    // 删除堆头操作要进行下移操作
    // 删除堆头 实际上是移除了堆的末尾元素,将末尾元素值赋值给堆头元素
    // 从堆头进行下移操作,目的删除堆头元素后不会影响堆的数据结构
    shiftDown(index) {
        const leftIndex = this.getLeftIndex(index);
        const rightIndex = this.getRightIndex(index);
        if(this.heap[leftIndex] < this.heap[index]) {
            this.swap(leftIndex,index);
            this.shiftDown(leftIndex);
        }
        if(this.heap[rightIndex] < this.heap[index]) {
            this.swap(rightIndex,index);
            this.shiftDown(rightIndex);
        }
    }
    // 向堆中插入节点
    insert(value) {
        // 将值插入到堆的末尾
        this.heap.push(value);
        // 上移操作,与父节点进行比较
        this.shiftUp(this.heap.length - 1)
    }
    // 删除堆头节点
    pop() {
        // 移除堆尾,用堆尾节点替代堆头节点
        // 不能直接删除堆头,否则会破坏堆的结构
        this.heap[0] = this.heap.pop();
        // 执行下移操作
        this.shiftDown(0);
    }
    // 获取堆顶
    peek(){
        return this.heap[0];
    }
    // 获取堆的长度
    size(){
        return this.heap.length;
    }
}
const h = new MinHeap();
h.insert(3)
h.insert(2)
h.insert(1)
h.pop();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值