介紹大根堆小根堆

文章目錄

      • 一、核心定義與結構特性
        • 示例(以“數組存儲堆”為例)
      • 二、堆的兩個核心操作
        • 1. 插入操作(以小根堆為例)
        • 2. 刪除極值操作(以小根堆為例,刪除根節點的最小值)
      • 三、小根堆 vs 大根堆:對比與適用場景
      • 四、典型應用場景
      • 代碼示例
      • 總結

小根堆(Min-Heap)和大根堆(Max-Heap)是完全二叉樹的兩種特殊形式,屬于“堆(Heap)”數據結構的核心類型,核心特性是“父節點與子節點的優先級關系固定”,主要用于高效獲取極值(最小值/最大值)和實現排序、優先隊列等場景。

一、核心定義與結構特性

堆的本質是“完全二叉樹”(除最后一層外,每一層節點數均滿;最后一層節點從左到右連續排列,不允許中間空缺),其核心規則由“根堆類型”決定:

類型核心規則(父子節點關系)關鍵特征
小根堆(Min-Heap)任意父節點的值 其左右子節點的值整個堆的最小值一定在根節點
大根堆(Max-Heap)任意父節點的值 其左右子節點的值整個堆的最大值一定在根節點
示例(以“數組存儲堆”為例)

堆通常用數組存儲(利用完全二叉樹的索引特性,無需額外存儲指針),若父節點索引為i(從0開始),則:

  • 左子節點索引:2i + 1

  • 右子節點索引:2i + 2

  • 小根堆數組示例:[1, 3, 2, 8, 5, 4](根為1,每個父節點≤子節點)

  • 大根堆數組示例:[8, 5, 4, 3, 1, 2](根為8,每個父節點≥子節點)

二、堆的兩個核心操作

堆的功能依賴“插入”和“刪除極值”兩個操作,操作后需通過“堆化(Heapify)”維持堆的規則,避免結構紊亂。

1. 插入操作(以小根堆為例)
  1. 尾插:將新元素插入數組的最后一位(對應完全二叉樹的最后一個節點);
  2. 向上堆化(Sift Up):比較新元素與父節點的值,若新元素更小(小根堆規則),則交換兩者;重復此過程,直到新元素≥父節點或成為根節點,堆規則恢復。
2. 刪除極值操作(以小根堆為例,刪除根節點的最小值)
  1. 替換根:數組滿的情況下插入更優數據或需要取出根節點時,將數組最后一位元素移到根節點位置(覆蓋并刪除原根節點);
  2. 向下堆化(Sift Down):比較根節點與左右子節點的最小值,若根節點更大,則與最小子節點交換;重復此過程,直到根節點≤子節點或成為葉子節點,堆規則恢復。

三、小根堆 vs 大根堆:對比與適用場景

兩者核心差異在于“極值位置”和“堆化時的比較邏輯”,適用場景隨需求(取最小/最大值)而定:

維度小根堆(Min-Heap)大根堆(Max-Heap)
極值位置根節點(O(1)獲取最小值)根節點(O(1)獲取最大值)
堆化比較邏輯向上堆化:新元素<父節點則交換向上堆化:新元素>父節點則交換
向下堆化:父節點>子節點最小值則交換向下堆化:父節點<子節點最大值則交換
核心適用場景1. 快速獲取/刪除最小值(如優先隊列中“最小任務優先執行”);
2. 海量數據中找Top K(如找最大的100個數,用小根堆維護候選集);
3. 實現堆排序(升序排序)
1. 快速獲取/刪除最大值(如優先隊列中“最大任務優先執行”);
2. 海量數據中找Top K(如找最小的100個數,用大根堆維護候選集);
3. 實現堆排序(降序排序)
時間復雜度插入、刪除極值均為 O(log n)(堆化過程最多遍歷樹的高度,完全二叉樹高度為log?n)同小根堆,插入、刪除極值均為 O(log n)

四、典型應用場景

  1. 優先隊列(Priority Queue)

堆是優先隊列的底層實現,例如:

  • 小根堆實現“最小優先隊列”(如操作系統中“短任務優先”調度);
  • 大根堆實現“最大優先隊列”(如電商平臺“高優先級訂單優先處理”)。
  1. 堆排序
  • 用大根堆實現降序排序:反復取出根節點(最大值)放到數組末尾,再堆化剩余元素;
  • 用小根堆實現升序排序:反復取出根節點(最小值)放到數組末尾,再堆化剩余元素。
  1. Top K 問題
  • 找“最大的K個數”:用大小為K的小根堆,遍歷數據時,比堆頂大的元素替換堆頂并堆化,最終堆內即Top K;
  • 找“最小的K個數”:用大小為K的大根堆,遍歷數據時,比堆頂小的元素替換堆頂并堆化,最終堆內即Top K。

代碼示例

/*** 使用java數組實現一個n=10的小根堆,實現包括插入和刪除根節點方法**/
public class MinHeap {private int[] heap;  // 存儲堆的數組private int size;    // 當前堆的大小private int capacity; // 堆的最大容量// 構造函數,初始化容量為10的小根堆public MinHeap() {this.capacity = 10;this.heap = new int[capacity];this.size = 0;}// 獲取父節點索引private int parent(int i) {return (i - 1) / 2;}// 獲取左子節點索引private int leftChild(int i) {return 2 * i + 1;}// 獲取右子節點索引private int rightChild(int i) {return 2 * i + 2;}// 交換兩個索引位置的元素private void swap(int i, int j) {int temp = heap[i];heap[i] = heap[j];heap[j] = temp;}// 插入元素到堆中public void insert(int value) {if (size == capacity) {System.out.println("堆已滿,無法插入新元素");return;}// 先將新元素插入到最后位置size++;int i = size - 1;heap[i] = value;// 向上堆化:如果新元素小于其父節點,則交換它們while (i != 0 && heap[parent(i)] > heap[i]) {swap(i, parent(i));i = parent(i);}}// 向下堆化:當根節點被刪除后,重新維護堆的性質private void heapify(int i) {int left = leftChild(i);int right = rightChild(i);int smallest = i;// 找到當前節點、左子節點、右子節點中的最小值if (left < size && heap[left] < heap[smallest]) {smallest = left;}if (right < size && heap[right] < heap[smallest]) {smallest = right;}// 如果最小值不是當前節點,則交換并繼續向下堆化if (smallest != i) {swap(i, smallest);heapify(smallest);}}// 刪除并返回根節點(最小值)public int deleteRoot() {if (size <= 0) {throw new IllegalStateException("堆為空,無法刪除元素");}if (size == 1) {size--;return heap[0];}// 保存根節點的值int root = heap[0];// 將最后一個元素移到根節點位置,并減小堆大小heap[0] = heap[size - 1];size--;// 從根節點開始向下堆化heapify(0);return root;}// 打印堆中的元素public void printHeap() {System.out.print("小根堆元素: ");for (int i = 0; i < size; i++) {System.out.print(heap[i] + " ");}System.out.println();}// 測試小根堆的實現public static void main(String[] args) {MinHeap minHeap = new MinHeap();// 插入元素minHeap.insert(5);minHeap.insert(3);minHeap.insert(8);minHeap.insert(1);minHeap.insert(6);minHeap.insert(2);minHeap.printHeap(); // 應該輸出: 1 3 2 5 6 8// 刪除根節點(最小值)System.out.println("刪除的根節點值: " + minHeap.deleteRoot()); // 應該輸出: 1minHeap.printHeap(); // 應該輸出: 2 3 8 5 6// 繼續插入元素直到堆滿minHeap.insert(4);minHeap.insert(7);minHeap.insert(9);minHeap.insert(0);minHeap.insert(10);minHeap.printHeap(); // 應該輸出: 0 2 8 3 6 10 4 5 7 9// 嘗試插入第11個元素(堆已滿)minHeap.insert(11); // 應該提示堆已滿}
}

總結

  • 小根堆和大根堆是“完全二叉樹+固定父子優先級”的結合,核心價值是O(1)獲取極值、O(log n)插入/刪除,效率遠高于數組(O(n)查找極值);
  • 選擇哪種堆,取決于場景需要“快速獲取最小值”還是“快速獲取最大值”,兩者操作邏輯對稱,僅比較方向不同。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/93310.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/93310.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/93310.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Html網頁模板】賽博朋克數據分析大屏網頁

目錄專欄導讀? 項目概述&#x1f3a8; 設計理念&#x1f6e0;? 技術架構核心技術棧設計模式&#x1f3af; 核心功能1. 視覺效果系統&#x1f308; 色彩體系2. 數據可視化模塊&#x1f4ca; 主圖表系統&#x1f4c8; 性能監控面板3. 實時數據流系統? 數據流動畫&#x1f4ca;…

【經典上穿突破】副圖/選股指標,雙均線交叉原理,對價格波動反應靈敏,適合捕捉短期啟動點

【經典上穿突破】副圖/選股指標&#xff0c;雙均線交叉原理&#xff0c;對價格波動反應靈敏&#xff0c;適合捕捉短期啟動點 這是一款結合短線與中線信號的趨勢跟蹤指標&#xff0c;通過雙均線交叉原理捕捉股價突破時機&#xff0c;適用于個股分析和盤中選股。 核心功能模塊&…

RK3568 NPU RKNN(四):RKNN-ToolKit2性能和內存評估

文章目錄1、前言2、目標3、完整的測試程序4、運行測試程序5、程序拆解6、總結1、前言 本文僅記錄本人學習過程&#xff0c;不具備教學指導意義。 2、目標 使用野火提供的示例程序&#xff0c;體驗 RKNN-ToolKit2 在PC端使用連板推理&#xff0c;進行性能和內存評估。 3、完…

ASP.NET 上傳文件安全檢測方案

一、前端初步過濾&#xff08;防誤操作&#xff09;<!-- HTML部分 --><input type"file" id"fileUpload" accept".jpg,.png,.pdf,.docx" /><button onclick"validateFile()">上傳</button><script>func…

Nacos Server 3.0.x安裝教程

前言 注&#xff1a; 1.Nacos Server 3.0.x 要求 JDK版本不低于17。 2.Nacos 2.2.0 及以上版本需要 Java 11 或更高版本。 3.Java 8&#xff0c;需要下載 Nacos 2.1.x 及以下版本 JDK17安裝 JDK官方下載地址&#xff1a;Oracle官網JDK下載地址 JDK17&#xff1a;JDK17下載地…

【數據庫干貨】六大范式速記

1NF、2NF、3NF、BCNF、4NF、5NF都是數據庫設計中的范式&#xff08;Normalization&#xff09;&#xff0c;用于確保數據庫中的數據結構盡可能地減少冗余&#xff0c;避免更新異常、插入異常、刪除異常等問題&#xff0c;從而提高數據的存儲效率和一致性。 本篇文章簡單講解下各…

Java開發主流框架搭配詳解及學習路線指南

文章目錄一、前言&#x1f517;二、主流Java框架搭配2.1 Spring Boot MyBatis-Plus Spring Cloud2.2 Spring Boot Spring Data JPA Spring Cloud2.3 Quarkus/Vert.x (響應式編程棧)三、技術選型建議四、Java學習路線指南階段1&#xff1a;Java基礎 (4-6周)階段2&#xff1a…

flutter-使用device_info_plus獲取手機設備信息完整指南

文章目錄1. 概述2. 安裝與配置3. 基本使用方法3.1. 創建實例3.2. 區分平臺獲取信息4. 詳細信息獲取4.1. Android 設備信息4.2. iOS 設備信息4.3. Web 瀏覽器信息4.4. Windows 設備信息5. 實戰示例6. 注意事項6.1. 權限問題6.2. 隱私保護6.3. 平臺差異處理6.4. 性能考慮7. 常見問…

Java 時間處理 API 全解析:從 JDK7 到 JDK8 的演進

個人主頁-愛因斯晨 友友們&#xff0c;互三咯~ 目錄 個人主頁-愛因斯晨 ?編輯 前言 一、JDK7 時間處理基石 ——Date 類 &#xff08;一&#xff09;Date 類基本功能 &#xff08;二&#xff09;Date 類的局限性 二、格式化時間好幫手 ——SimpleDateFormat 類 &#…

duiLib 實現鼠標拖動標題欄時,窗口跟著拖動

1、布局文件&#xff0c;窗口需設置可拖動的標題欄區域&#xff1a;2、HandleMessage函數中&#xff0c;處理WM_LBUTTONDOWN消息&#xff0c;判斷鼠標在標題欄&#xff0c;讓系統處理窗口移動。代碼片段如下&#xff1a;else if (uMsg WM_LBUTTONDOWN) {// 獲取鼠標點擊坐標PO…

圖解嵌入式硬件知識庫體系

構建一個嵌入式硬件知識庫體系需要涵蓋嵌入式系統設計、開發和應用的各個方面,內容全面且系統化,適合不同層次的用戶。本文是一個結構化的嵌入式硬件知識庫體系,包含主要內容模塊及其詳細說明。 @startmindmap * 嵌入式硬件知識庫體系 ** 1. 嵌入式系統基礎 *** 概述與定義 …

機器學習的特征工程(特征構造、特征選擇、特征轉換和特征提取)詳解

特征工程是機器學習中至關重要的一步&#xff0c;它直接影響模型的性能和泛化能力。特征構造、特征選擇、特征轉換和特征提取——構成了特征工程的核心流程。下面我來系統地梳理一下它們的定義、方法和應用場景&#xff1a; 整理 by Moshow鄭鍇https://zhengkai.blog.csdn.net/…

Force Dimension觸覺力反饋設備在外科手術機器人遙操作和訓練中的應用

觸覺力反饋設備通過傳感器-執行器-信號處理閉環系統&#xff0c;在外科手術機器人領域實現了從遠程手術操作到虛擬訓練的全流程革新。外科手術機器人外科醫生廣博的專業知識往往受限于他們的主要工具——手。機器人的精確度和靈活性遠遠超過人手。然而&#xff0c;目前機器人還…

【網絡與爬蟲 00】試讀

網絡爬蟲技術全棧指南&#xff1a;從入門到AI時代的數據采集革命 關鍵詞&#xff1a;網絡爬蟲、Python爬蟲、數據采集、反爬技術、分布式爬蟲、AI爬蟲、Scrapy框架、自動化數據提取、爬蟲架構設計 摘要&#xff1a;本專欄是最全面的網絡爬蟲技術指南&#xff0c;涵蓋從基礎框架…

[Chat-LangChain] 前端用戶界面 | 核心交互組件 | 會話流管理

鏈接&#xff1a;https://python.langchain.com/docs/tutorials/qa_chat_history/ Chat-LangChain技術棧 : LangChainLangGraphNext.jsWeaviate (向量存儲)OpenAI (嵌入模型) docs&#xff1a;chat-langchain Chat LangChain 是一個智能聊天機器人&#xff0c;專為解答Lang…

編寫和運行 Playbook

編寫和運行 Playbook Playbook 介紹 adhoc 命令可以作為一次性命令對一組主機運行一項簡單的任務。不過&#xff0c;若要真正發揮Ansible的能力&#xff0c;需要使用功能 playbook。 playbook 是一個文本文件&#xff0c;其中包含由一個或多個按特定順序運行的play組成的列表。…

uniapp手機端video標簽層級過高問題

當我們想以視頻作為背景時&#xff0c;其他dom通過定位顯示在視頻上方&#xff0c;h5頁面上調試發現可以正常使用&#xff0c;效果如下&#xff1a; 當放在手機上看&#xff0c;會發現&#xff0c;僅僅剩一個視頻&#xff0c;本應在視頻上層的元素不見了。 經過一番排查&#x…

【MyBatis批量更新實現】按照list傳入批量更新

學習目標&#xff1a; <update id"updateModelEngineeringSpatialNode" parameterType"com.mxpt.model.manage.domain.ModelEngineeringSpatialNode">update model_engineering_spatial_node<trim prefix"SET" suffixOverrides",&…

VOFA+ 顯示數據、波形

本篇&#xff0c;以最常用的串口通信作展示&#xff0c;示范如何通過VOFA顯示數據波形。 一、VOFA 下載 VOFA 是一款面向嵌入式開發的上位機軟件&#xff0c;專注于硬件數據實時可視化與調試。它通過高效協議&#xff08;如FireWater、JustFloat&#xff09;將原始字節流轉化為…

MySQL 插入數據提示字段超出范圍?一招解決 DECIMAL 類型踩坑

MySQL 插入數據提示字段超出范圍&#xff1f;一招解決 DECIMAL 類型踩坑 在日常數據庫操作中&#xff0c;我們經常會遇到各種字段類型相關的問題。今天就來聊聊一個常見的錯誤&#xff1a;插入數據時提示字段值超出范圍&#xff0c;以實際案例帶你搞懂 MySQL 中 DECIMAL 類型的…