当前位置:首页 > JavaScript

js实现堆

2026-02-02 07:01:10JavaScript

堆的基本概念

堆是一种特殊的完全二叉树,分为最大堆和最小堆。最大堆的每个父节点值大于或等于子节点值,最小堆的每个父节点值小于或等于子节点值。堆常用于优先队列、堆排序等场景。

堆的数组表示

堆通常用数组表示,对于索引i的节点:

  • 父节点索引:Math.floor((i - 1) / 2)
  • 左子节点索引:2 * i + 1
  • 右子节点索引:2 * i + 2

最小堆实现代码

class MinHeap {
  constructor() {
    this.heap = [];
  }

  // 获取父节点索引
  getParentIndex(index) {
    return Math.floor((index - 1) / 2);
  }

  // 获取左子节点索引
  getLeftChildIndex(index) {
    return 2 * index + 1;
  }

  // 获取右子节点索引
  getRightChildIndex(index) {
    return 2 * index + 2;
  }

  // 交换两个节点
  swap(index1, index2) {
    [this.heap[index1], this.heap[index2]] = [this.heap[index2], this.heap[index1]];
  }

  // 上移操作
  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 leftChildIndex = this.getLeftChildIndex(index);
    const rightChildIndex = this.getRightChildIndex(index);
    let minIndex = index;

    if (leftChildIndex < this.heap.length && this.heap[leftChildIndex] < this.heap[minIndex]) {
      minIndex = leftChildIndex;
    }

    if (rightChildIndex < this.heap.length && this.heap[rightChildIndex] < this.heap[minIndex]) {
      minIndex = rightChildIndex;
    }

    if (minIndex !== index) {
      this.swap(index, minIndex);
      this.shiftDown(minIndex);
    }
  }

  // 插入元素
  insert(value) {
    this.heap.push(value);
    this.shiftUp(this.heap.length - 1);
  }

  // 删除堆顶元素
  pop() {
    if (this.heap.length === 0) return null;
    const top = this.heap[0];
    const last = this.heap.pop();
    if (this.heap.length > 0) {
      this.heap[0] = last;
      this.shiftDown(0);
    }
    return top;
  }

  // 获取堆顶元素
  peek() {
    return this.heap.length > 0 ? this.heap[0] : null;
  }

  // 获取堆大小
  size() {
    return this.heap.length;
  }
}

最大堆实现代码

将最小堆的比较符号反转即可实现最大堆:

class MaxHeap {
  // ... (其他方法与MinHeap相同)

  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 leftChildIndex = this.getLeftChildIndex(index);
    const rightChildIndex = this.getRightChildIndex(index);
    let maxIndex = index;

    if (leftChildIndex < this.heap.length && this.heap[leftChildIndex] > this.heap[maxIndex]) {  // 改为大于
      maxIndex = leftChildIndex;
    }

    if (rightChildIndex < this.heap.length && this.heap[rightChildIndex] > this.heap[maxIndex]) {  // 改为大于
      maxIndex = rightChildIndex;
    }

    if (maxIndex !== index) {
      this.swap(index, maxIndex);
      this.shiftDown(maxIndex);
    }
  }
}

堆的应用示例

// 创建最小堆
const minHeap = new MinHeap();
minHeap.insert(3);
minHeap.insert(2);
minHeap.insert(1);
console.log(minHeap.pop()); // 输出1

// 创建最大堆
const maxHeap = new MaxHeap();
maxHeap.insert(1);
maxHeap.insert(2);
maxHeap.insert(3);
console.log(maxHeap.pop()); // 输出3

堆排序实现

利用堆可以实现堆排序算法:

js实现堆

function heapSort(arr) {
  const heap = new MinHeap();
  const sorted = [];

  // 构建堆
  for (let num of arr) {
    heap.insert(num);
  }

  // 依次取出堆顶元素
  while (heap.size() > 0) {
    sorted.push(heap.pop());
  }

  return sorted;
}

console.log(heapSort([3, 1, 4, 1, 5, 9, 2, 6])); // [1, 1, 2, 3, 4, 5, 6, 9]

标签: js
分享给朋友:

相关文章

jquery.js

jquery.js

jQuery 简介 jQuery 是一个快速、简洁的 JavaScript 库,用于简化 HTML 文档遍历、事件处理、动画设计和 Ajax 交互。它的设计宗旨是“Write Less, Do Mor…

js实现文件下载

js实现文件下载

使用 a 标签下载文件 通过动态创建 a 标签并设置 download 属性实现文件下载。适用于已知文件 URL 或 Blob 数据的情况。 function downloadFile(url, f…

js如何实现继承

js如何实现继承

原型链继承 通过将子类的原型指向父类的实例实现继承。子类实例能够访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Parent…

js防抖和节流实现

js防抖和节流实现

防抖(Debounce)的实现 防抖的核心思想是在事件被触发后,延迟执行回调函数。如果在延迟时间内再次触发事件,则重新计时。适用于输入框搜索、窗口大小调整等场景。 function debounce…

js实现抽奖

js实现抽奖

实现抽奖功能的基本思路 抽奖功能的核心是随机选择奖项并展示结果。可以通过数组存储奖项,利用随机数生成索引,最后通过动画增强用户体验。 准备奖项数据 定义一个数组存储奖项信息,每个奖项可以包含名称、图…

js实现文字滚动

js实现文字滚动

实现文字滚动的几种方法 使用CSS动画实现滚动 通过CSS的@keyframes和transform属性可以实现平滑的文字滚动效果。 <style> .scroll-text { w…