JavaScript实现 简易 堆


有两个原始操作用于保证插入或删除节点以后堆是一个有效的最大堆或者最小堆:

  • shiftUp(): 如果一个节点比它的父节点大(最大堆)或者小(最小堆),那么需要将它同父节点交换位置。这样是这个节点在数组的位置上升。
  • shiftDown(): 如果一个节点比它的子节点小(最大堆)或者大(最小堆),那么需要将它向下移动。这个操作也称作“堆化(heapify)”。

shiftUp 或者 shiftDown 是一个递归的过程,所以它的时间复杂度是 O(log n)。

基于这两个原始操作还有一些其他的操作:

  • insert(value): 在堆的尾部添加一个新的元素,然后使用 shiftUp 来修复对。
  • remove(): 移除并返回最大值(最大堆)或者最小值(最小堆)。为了将这个节点删除后的空位填补上,需要将最后一个元素移到根节点的位置,然后使用 shiftDown 方法来修复堆。

有一个挺恶心人的地方就是JS的number数据类型会导致需要向下取整才能对heap数组进行上升操作,否则就会有小数点的情况

这里是最大堆,最小堆稍微修改一下比较方式就行

let heap = [];
function swap(idx1,idx2){
  let temp;
  temp = heap[idx1];
  heap[idx1] = heap[idx2];
  heap[idx2] = temp;
}
function shiftup(idx){
  let _idx = Math.floor((idx - 1) / 2);
  if(idx != 0 && heap[_idx] < heap[idx]){
  swap(_idx,idx);
  shiftup(_idx);
}
}
function shiftDown(idx){
  if(idx * 2 + 1 < heap.length && heap[idx * 2 + 1] > heap[idx]){
    swap(idx * 2 + 1,idx);
    shiftDown(idx * 2 + 1);
  }else if(idx * 2 + 2 < heap.length && heap[idx * 2 + 2] > heap[idx]){
    swap(idx * 2 + 2,idx);
    shiftDown(idx * 2 + 2);
  }
}
function insert(val){
  heap.push(val);
  shiftup(heap.length - 1);
}
function remove(){
  swap(0,heap.length - 1);
  heap.pop();
  shiftDown(0);
  return heap[0];
}
insert(1);
insert(3);
insert(2);
insert(5);
remove();
insert(4);
insert(6);
remove();
console.log(heap);//4

参考:https://www.jianshu.com/p/6b526aa481b1


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM