当前位置:首页 > JavaScript

js堆实现

2026-02-01 14:09:05JavaScript

堆的概念与特点

堆(Heap)是一种特殊的完全二叉树,分为最大堆和最小堆。最大堆中,父节点的值大于或等于子节点的值;最小堆中,父节点的值小于或等于子节点的值。堆常用于实现优先队列。

堆的存储结构

堆通常使用数组存储,利用完全二叉树的性质:

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

堆的基本操作实现

插入元素(上浮操作)

向堆中插入元素时,先将元素放到数组末尾,然后通过“上浮”调整堆结构:

js堆实现

function insert(heap, value) {
  heap.push(value);
  let index = heap.length - 1;
  while (index > 0) {
    const parentIndex = Math.floor((index - 1) / 2);
    if (heap[index] <= heap[parentIndex]) break;
    [heap[index], heap[parentIndex]] = [heap[parentIndex], heap[index]];
    index = parentIndex;
  }
}

删除堆顶元素(下沉操作)

删除堆顶元素后,将数组末尾元素移到堆顶,然后通过“下沉”调整堆结构:

function extractMax(heap) {
  if (heap.length === 0) return null;
  const max = heap[0];
  heap[0] = heap.pop();
  let index = 0;
  while (true) {
    const leftChild = 2 * index + 1;
    const rightChild = 2 * index + 2;
    let largest = index;
    if (leftChild < heap.length && heap[leftChild] > heap[largest]) {
      largest = leftChild;
    }
    if (rightChild < heap.length && heap[rightChild] > heap[largest]) {
      largest = rightChild;
    }
    if (largest === index) break;
    [heap[index], heap[largest]] = [heap[largest], heap[index]];
    index = largest;
  }
  return max;
}

堆的构建

可以通过“堆化”操作将无序数组构建为堆:

js堆实现

function buildHeap(arr) {
  const heap = [...arr];
  for (let i = Math.floor(heap.length / 2) - 1; i >= 0; i--) {
    heapify(heap, i);
  }
  return heap;
}

function heapify(heap, index) {
  const left = 2 * index + 1;
  const right = 2 * index + 2;
  let largest = index;
  if (left < heap.length && heap[left] > heap[largest]) {
    largest = left;
  }
  if (right < heap.length && heap[right] > heap[largest]) {
    largest = right;
  }
  if (largest !== index) {
    [heap[index], heap[largest]] = [heap[largest], heap[index]];
    heapify(heap, largest);
  }
}

堆排序实现

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

function heapSort(arr) {
  const heap = buildHeap(arr);
  const sorted = [];
  while (heap.length > 0) {
    sorted.unshift(extractMax(heap));
  }
  return sorted;
}

优先队列实现

基于堆可以轻松实现优先队列:

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

  enqueue(value) {
    insert(this.heap, value);
  }

  dequeue() {
    return extractMax(this.heap);
  }

  peek() {
    return this.heap[0];
  }

  size() {
    return this.heap.length;
  }
}

注意事项

  • 上述代码实现的是最大堆,若要实现最小堆,只需将比较逻辑中的 > 改为 <
  • 堆的时间复杂度:
    • 插入操作:O(log n)
    • 删除操作:O(log n)
    • 构建堆:O(n)
    • 堆排序:O(n log n)

标签: js
分享给朋友:

相关文章

css3结合js制作

css3结合js制作

CSS3 结合 JavaScript 制作动态效果 CSS3 和 JavaScript 结合可以实现丰富的动态效果,包括动画、交互和响应式设计。以下是几种常见的实现方式: CSS3 动画与 Java…

vue.js实现轮播

vue.js实现轮播

Vue.js 实现轮播功能 使用第三方库(推荐) Vue.js 生态中有许多成熟的轮播组件库,例如 vue-awesome-swiper 或 swiper,它们功能丰富且易于集成。 安装 swipe…

js实现跳转

js实现跳转

使用 window.location 跳转 通过修改 window.location.href 实现页面跳转,这是最常用的方法。 window.location.href = 'https://…

js实现分页

js实现分页

分页的基本实现思路 在JavaScript中实现分页功能通常需要结合前端和后端逻辑。前端负责渲染分页控件和处理用户交互,后端负责提供分页数据。 前端分页实现 纯前端分页适用于数据量较小的情况,可以直…

js 实现继承

js 实现继承

原型链继承 通过让子类的原型对象指向父类的实例来实现继承。子类实例可以访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Par…

js实现选项卡

js实现选项卡

实现选项卡的基本思路 选项卡通常由一组标签和对应的内容面板组成。点击标签时,显示对应的内容面板,隐藏其他面板。实现这一效果需要结合HTML结构、CSS样式和JavaScript交互逻辑。 HTML结…