堆(二叉堆)


堆和二叉堆的介紹

堆的定義

堆(heap),這里所說的堆是數據結構中的堆,而不是內存模型中的堆。堆通常是一個可以被看做一棵樹,它滿足下列性質:
[性質一] 堆中任意節點的值總是不大於(不小於)其子節點的值;
[性質二] 堆總是一棵完全樹。
將任意節點不大於其子節點的堆叫做最小堆或小根堆,而將任意節點不小於其子節點的堆叫做最大堆或大根堆。常見的堆有二叉堆、左傾堆、斜堆、二項堆、斐波那契堆等等。

 

二叉堆的定義

二叉堆是完全二元樹或者是近似完全二元樹,它分為兩種:最大堆和最小堆。
最大堆:父結點的鍵值總是大於或等於任何一個子節點的鍵值;最小堆:父結點的鍵值總是小於或等於任何一個子節點的鍵值。示意圖如下:

 

二叉堆一般都通過"數組"來實現。數組實現的二叉堆,父節點和子節點的位置存在一定的關系。有時候,我們將"二叉堆的第一個元素"放在數組索引0的位置,有時候放在1的位置。當然,它們的本質一樣(都是二叉堆),只是實現上稍微有一丁點區別。

假設"第一個元素"在數組中的索引為 0 的話,則父節點和子節點的位置關系如下:

(01) 索引為i的左孩子的索引是 (2*i+1);

(02) 索引為i的右孩子的索引是 (2*i+2);

(03) 索引為i的父結點的索引是 floor((i-1)/2);

 

假設"第一個元素"在數組中的索引為 1 的話,則父節點和子節點的位置關系如下:

(01) 索引為i的左孩子的索引是 (2*i);

(02) 索引為i的右孩子的索引是 (2*i+1);

(03) 索引為i的父結點的索引是 floor(i/2);

 

二叉堆的圖文解析

在前面,我們已經了解到:"最大堆"和"最小堆"是對稱關系。這也意味着,了解其中之一即可。本節的圖文解析是以"最大堆"來進行介紹的。

二叉堆的核心是"添加節點"和"刪除節點",理解這兩個算法,二叉堆也就基本掌握了。下面對它們進行介紹。

 

1. 添加

假設在最大堆[90,80,70,60,40,30,20,10,50]種添加85,需要執行的步驟如下:

如上圖所示,當向最大堆中添加數據時:先將數據加入到最大堆的最后,然后盡可能把這個元素往上挪,直到挪不動為止!
將85添加到[90,80,70,60,40,30,20,10,50]中后,最大堆變成了[90,85,70,60,80,30,20,10,50,40]。

2. 刪除

假設從最大堆[90,85,70,60,80,30,20,10,50,40]中刪除90,需要執行的步驟如下:

從[90,85,70,60,80,30,20,10,50,40]刪除90之后,最大堆變成了[85,80,70,60,40,30,20,10,50]。
如上圖所示,當從最大堆中刪除數據時:先刪除該數據,然后用最大堆中最后一個的元素插入這個空位;接着,把這個“空位”盡量往上挪,直到剩余的數據變成一個最大堆。

注意:考慮從最大堆[90,85,70,60,80,30,20,10,50,40]中刪除60,執行的步驟不能單純的用它的子節點來替換;而必須考慮到"替換后的樹仍然要是最大堆"!

 
 
文章內容摘抄於:
二叉堆(一)之 圖文解析 和 C語言的實現 - 如果天空不死 - 博客園


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM