欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

学习一下小顶堆

程序员文章站 2022-03-27 09:37:23
...

概念入门

完全二叉树

一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树

堆是一棵完全二叉树,其存储结构一般用的是数组

小顶堆

小顶堆就是堆顶的元素是当前子树里最小的一个元素的堆,对任意非叶子节点 有 Key[i]<=key[2i+1]&&Key[i]<=key[2i+2];

操作

构造

构造一棵小顶堆 即在存储数组的末尾添加一个元素 然后判断其能否满足小顶堆的性质,不满足即 把他与父节点交换位置,重复此步骤直到找到正确的位置:

  1. /*
  2. react scheduler React v0.20.1
  3. */
  4. function siftUp(heap,node){
  5. let nodeIndex = heap.length;
  6. heap[nodeIndex] = node;
  7. while(true){
  8. /*
  9. 假设某个根节点为i 则其
  10. left 为 2i + 1
  11. right 2i + 2
  12. * left - 1 是 2i
  13. * right - 1 是 2i + 1;
  14. * 然后再右移相当于除以2向下取整都能得到正确的
  15. * 父节点位置 至于这里为什么用无符号右移而没有用>> 这点尚未清楚
  16. */
  17. let parentNodeIndex = nodeIndex - 1 >>> 1
  18. let parentNode = heap[parentNodeIndex]
  19. if(
  20. parentNode !== undefined
  21. &&
  22. parentNode > node
  23. ){
  24. heap[parentNodeIndex] = node
  25. heap[nodeIndex] = parentNode
  26. nodeIndex = parentNodeIndex
  27. }else{
  28. return;
  29. }
  30. }
  31. }

删除

对于堆的删除来说,是指删除堆顶的元素 同时取出最后一个元素 从堆顶开始 找到左右子节点 选择其中比较小并且小于他的元素 依次比较 交换位置,重复此步骤直到满足小顶堆的性质:

  1. function siftDown(heap){
  2. let parentIndex = 0;
  3. let parentNode = heap[0];
  4. let lastNode = heap.pop();
  5. const L = heap.length;
  6. while( parentIndex < L ){
  7. let leftIndex = 2*parentIndex + 1;
  8. let rightIndex = leftIndex + 1;
  9. let left = heap[leftIndex];
  10. let right = heap[rightIndex]
  11. if( rightIndex < L ){//左右子节点都存在
  12. if( left < lastNode ){
  13. if( right < left){
  14. heap[parentIndex] = right;
  15. heap[rightIndex] = lastNode;
  16. parentIndex = rightIndex;
  17. }else{
  18. heap[parentIndex] = left;
  19. heap[leftIndex] = lastNode;
  20. parentIndex = leftIndex;
  21. }
  22. }else if( right < lastNode ){
  23. heap[parentIndex] = right;
  24. heap[rightIndex] = lastNode;
  25. parentIndex = rightIndex;
  26. }else{
  27. break;
  28. }
  29. }else if( leftIndex < L){//只有左子节点
  30. if( left < lastNode ){
  31. heap[parentIndex] = left;
  32. heap[leftIndex] = lastNode;
  33. parentIndex = leftIndex;
  34. }else{
  35. break;
  36. }
  37. }else{
  38. break;
  39. }
  40. }
  41. return parentNode;
  42. }