首页 > 其他分享 >[数据结构学习笔记9] 堆(Heaps)

[数据结构学习笔记9] 堆(Heaps)

时间:2025-01-08 22:54:38浏览次数:1  
标签:Heaps index 笔记 heap largestIndex 数据结构 root 节点 myHeap

在日常生活中,我们常常有很多想法要去实现,但是时间有限,所以要把想法分优先级,哪个是最重要的,先做它。堆(heaps)是这样一个数据结构,它让你容易(O(1))的获取最高优先级的想法,并且提供了快速(O(log n))插入,移除想法操作。

 

堆分为最大堆和最小堆,最大堆就是说root是最大值,最小堆是说root是最小值。这里我们讨论的时候,讨论最大堆。最小堆的表示和处理方式和最大堆相反。

最大堆是一个Complete 二叉树,并且每个节点值都要大于它的子节点。

 

常见堆操作

插入节点

1. 如果树为空,则新节点为root节点

2. 如果树不为空,则从左往右,一次添加新的节点

3. 比较新节点和其父节点的大小,如果新节点大于父节点,则新节点和父节点互换

4. 重复步骤3,直到父节点大于新节点

移除节点,一般堆移除节点,指的是移除root

1. 把root和最后的叶子节点互换

2. 比较新的root节点和其孩子节点,如果新root比孩子节点小,那么把新root和两个孩子节点中较大的互换;重复这个步骤,直到新root节点比它的孩子节点大

 

代码实现(javascript)

这里我们要用数组的方式去表示堆。

请看这样一个堆:

                        50

                       |      |
                     15     18

                   |      |    |     |

                 14   2    13    1

               |     |    |

               2   3    0

用数组表示成这样:

50 15 18 14 2 13 1 2 3 0
0 1 2 3 4 5 6 7 8 9

1. 下标为i的节点的父节点,计算公式 Math.floor((i-1)/2)。注意这里适用于非root节点;

2. 下标为i的节点的左子节点,计算公式 2i+1。注意这里计算不能越界;

3. 下标为i的节点的右子节点,计算公式 2i+2。同样这里也不能越界。

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

   insert(value) {
       this.heap.push(value);
       this.#bubbleUp(this.heap.length - 1);
   }

   extractMax() {
        if (this.heap.length === 0) {
              return null;
         }
        if (this.heap.length === 1) {
              return this.heap.pop();
         }    
        const max = this.heap[0];
        const end = this.heap.pop();
        this.heap[0] = end;
        this.#bubbleDown(0);
        return max;
   }

   #bubbleUp(index) {
        if (index === 0) {
            return;
        }
        const parentIndex = Math.floor((index - 1) / 2);
        if (this.heap[index] > this.heap(parentIndex)) {
             [this.heap[index], this.heap[parentIndex]] = [this.heap[parentIndex], this.heap[index]];
             this.#bubbleUp(parentIndex);
        }
   }

   #bubbleDown(index) {
         const leftChildIndex = 2 * index + 1;
         const rightChildIndex = 2* index + 2;
         let largestIndex = index;
         if (leftChildIndex < this.heap.length && this.heap[leftChildIndex] > this.heap[largestIndex]) {
                largestIndex = leftChildIndex;
          }
         if (rightChildIndex < this.heap.length && this.heap[rightChildIndex] > this.heap[largestIndex]) {
                largestIndex = rightChildIndex;
          }
         if (largestIndex !== index) {
                [this.heap[index], this.heap[largestIndex]] = [this.heap[largestIndex], this.heap[index]];
                this.#bubbleDown(largestIndex);
          }
    }


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

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

    isEmpty() {
           return this.heap.length === 0;
     }
}

使用Heap

let myHeap = new Heap();
myHeap.insert(14);
myHeap.insert(18);
myHeap.insert(50);
myHeap.insert(1);
myHeap.insert(3);
myHeap.insert(15);
myHeap.insert(2);

myHeap.extractMax(); // 50

时间复杂度

动作 时间复杂度 空间复杂度
移除根节点 O(log n) O(1)
插入新节点 O(log n) O(1)

堆常应用于堆排序,优先队列,迪杰斯特拉算法发现图最短路径等等。

标签:Heaps,index,笔记,heap,largestIndex,数据结构,root,节点,myHeap
From: https://www.cnblogs.com/Eagle6970/p/18659402

相关文章

  • Win32汇编学习笔记07.筛选器异常
    Win32汇编学习笔记07.筛选器异常-C/C++基础-断点社区-专业的老牌游戏安全技术交流社区-BpSend.net钢琴od调试老师给的多媒体钢琴运行找到Piano的过程函数里去找到处理WM_KEYDOWN消息的那下个断点,然后按键断下来在这分析上图汇编代码:moveax,dwordptr[ebp+10]拿wPa......
  • CTF 之 Crypto (Cryptography) 学习笔记
    CTF之Crypto(Cryptography)Chapter0.前置知识群(Group)给定一个集合\(G\neq\emptyset\)以及二元代数运算\(\circ\),若满足:封闭性(Closure):\(\forallu,v\inG\),\(u\circv\inG\);结合律(Associativity):\(\forallu,v,w\inG\),\((u\circv)\circw=u\circ(v......
  • 学习进度笔记②
    今天学习的是林子雨编写的spark编程基础的第一章节的内容:Scala简介Scala是一门现代的多范式编程语言,平滑地集成了面向对象和函数式语言的特性,旨在以简练、优雅的方式来表达常用编程模式。Scala的设计吸收借鉴了许多种编程语言的思想,只有很少量特点是Scala自己独有的。Scala语言的......
  • 蓝桥杯python省赛备战day2--数组枚举--845数组中的最长山脉-枚举算法刷题学习笔记3--l
    写在前面的话:大家好,我是一名正在努力学习数据结构和算法的新手。这篇文章是我在学习python的各类数据结构以及基础算法过程中的一些笔记和心得,希望能和同样在学习该方面知识的朋友们分享。由于我的知识有限,文章中可能存在错误或不准确的地方,欢迎大家在评论区提出建议和指正。......
  • 2025 西电软工数据结构机考 Tip (By Felix)
    2025/01/07  18:30-20:30XDOJ 五道题  三道题即为满分近两年没有考过图和字符串,链表和树为重点内容(必考重点准备)2024年五道题:题目内容类型得分未知C语言未参加给出后序和中序遍历建树树未参加堆排序输出过程量排序未参加哈希表查找未参加未知链表未参加2025年五......
  • 印象笔记启动错误:缺失kernel32.dll文件
    印象笔记启动时出现“缺失kernel32.dll文件”的错误,通常意味着系统的kernel32.dll文件丢失或损坏。kernel32.dll是MicrosoftWindows操作系统中的核心动态链接库(DLL),负责提供基本的操作系统功能,如内存管理、线程管理、文件和I/O操作等。如果该文件缺失或损坏,将严重影响系统的正......
  • 数据结构与算法之二叉树: LeetCode 107. 二叉树的层序遍历 II (Ts版)
    二叉树的层序遍历IIhttps://leetcode.cn/problems/binary-tree-level-order-traversal-ii/description/描述给你二叉树的根节点root,返回其节点值自底向上的层序遍历。(即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)示例1输入:root=[3,9,20,null,nul......
  • Effective C++读书笔记——item12(自定义拷贝构造函数和拷贝赋值运算符可能出现的问题
    1.拷贝函数相关背景及编译器行为在面向对象系统中,拷贝构造函数和拷贝赋值运算符统称为拷贝函数,若不自行声明,编译器会按需生成默认的拷贝函数,其会拷贝被拷贝对象的全部数据。但当自行声明拷贝函数后,编译器若发现实现存在错误,往往不会主动提示,比如在新增数据成员却未更新拷贝函......
  • Effective C++读书笔记——item11(自赋值)
    自赋值相关问题自赋值情况示例明显的自赋值如w=w,还有不太容易辨别的情况,像a[i] =a[j](当i和j值相同)、*px=*py(当px和py指向同一对象)等,这些是由别名(有多种引用对象的方式)造成的,尤其在涉及引用、指针操作同类型多个对象以及继承体系中基类和派生类对象引用、指针转换时要考......
  • 【笔记】从华为云看4P理论的卓越践行者
              在当今竞争激烈的云计算市场中,华为云犹如一颗明星取得了令人瞩目的成绩。其成功的背后,离不开对4P营销理论——产品(Product)、价格(Price)、渠道(Place)、促销(Promotion)的巧妙运用与深度融合。这一经典的营销理论框架,在华为云的市场战略布局中被赋予了新的活......