二叉堆一般用數(shù)組來表示。例如,根節(jié)點在數(shù)組中的位置是0,第n個位置的子節(jié)點分別在2n+1和 2n+2。因此,第0個位置的子節(jié)點在1和2,1的子節(jié)點在3和4。以此類推。這種存儲方式便於尋找父節(jié)點和子節(jié)點。

如下圖的兩個堆:

1 11

/ \ / \

2 3 9 10

/ \ / \ / \ / \

4 5 6 7 5 6 7 8

/ \ / \ / \ / \

8 9 10 11 1 2 3 4

將這兩個堆保存在以1開始的數(shù)組中:

位置: 1 2 3 4 5 6 7 8 9 10 11

左圖: 1 2 3 4 5 6 7 8 9 10 11

右圖: 11 9 10 5 6 7 8 1 2 3 4

二叉堆造價信息

市場價 信息價 詢價
材料名稱 規(guī)格/型號 市場價
(除稅)
工程建議價
(除稅)
行情 品牌 單位 稅率 供應商 報價日期
二叉 S-8 查看價格 查看價格

13% 大連東方泰陶建材經銷部
二叉 200X120X100mm 查看價格 查看價格

金九方

13% 佛山市金九方陶瓷有限公司
二叉(四類色) S-8 查看價格 查看價格

比特利

13% 重慶比特利建材有限公司
二叉(三類色) S-8 查看價格 查看價格

比特利

13% 重慶比特利建材有限公司
二叉類色) S-8 查看價格 查看價格

比特利

13% 重慶比特利建材有限公司
二叉(一類色(紅胎)) S-8 查看價格 查看價格

比特利

13% 重慶比特利建材有限公司
類色) S-四 查看價格 查看價格

比特利

13% 重慶比特利建材有限公司
類色) T四 查看價格 查看價格

比特利

13% 重慶比特利建材有限公司
材料名稱 規(guī)格/型號 除稅
信息價
含稅
信息價
行情 品牌 單位 稅率 地區(qū)/時間
日本瓦[J-四] 查看價格 查看價格

韶關市2009年11月信息價
日本瓦[J-四] 查看價格 查看價格

韶關市2009年7月信息價
日本瓦[J-四] 查看價格 查看價格

韶關市2008年9月信息價
日本瓦[J-四] 查看價格 查看價格

韶關市2008年8月信息價
日本瓦[J-四] 查看價格 查看價格

韶關市2008年1月信息價
日本瓦[J-四] 查看價格 查看價格

韶關市2007年10月信息價
日本瓦[J-四] 查看價格 查看價格

韶關市2007年8月信息價
日本瓦[J-四] 查看價格 查看價格

韶關市2007年7月信息價
材料名稱 規(guī)格/需求量 報價數(shù) 最新報價
(元)
供應商 報價地區(qū) 最新報價時間
二叉 S-8|3645塊 1 查看價格 大連東方泰陶建材經銷部 遼寧  大連市 2015-11-24
二叉噴頭 DN15|6779個 1 查看價格 佛山市天興消防器材有限公司 廣東  佛山市 2015-10-20
、二叉 -|1臺 1 查看價格 深圳市力德森氣動工具有限公司    2017-06-12
二叉 200X120X100mm|9894塊 1 查看價格 佛山市金九方陶瓷有限公司 廣東  佛山市 2015-12-24
二叉頭路燈 高度5米,功率2×30W,光源LED|4臺 3 查看價格 深圳市奧瑞泰光電科技有限公司 廣東  廣州市 2019-01-28
超五類二叉水晶頭 PL45E-A 水晶頭類|7531盒 1 查看價格 廣州市唯康通信技術有限公司 廣東  廣州市 2015-05-27
存儲軟件 存儲語音、視頻|11 3 查看價格 北京恒泰鑫隆科技有限公司 湖北   2020-07-02
存儲 ≥40T 全閃存存儲IO模塊:支持16Gb FC|1個 1 查看價格 廣州市熹尚科技設備有限公司 全國   2021-09-09

概述

在二叉堆上可以進行插入節(jié)點、刪除節(jié)點、取出值最小的節(jié)點、減小節(jié)點的值等基本操作。

形式上看,它從頂點開始,每個節(jié)點有兩個子節(jié)點,每個子節(jié)點又各自有自己的兩個子節(jié)點;數(shù)值上看,每個節(jié)點的兩個子節(jié)點都比它大或和它相等。

要求

在二叉堆里我們要求:

* 最小的元素在頂端

* 每個元素都比它的父節(jié)點大,或者和父節(jié)點相等。

只要滿足這兩個條件,其他的元素怎么排都行。如上面的例子,最小的元素10在最頂端,第二小的元素20在10的下面,但是第三小的元素24在20的下面,也就是第三層,更大的30反而在第二層。

這樣一"堆"東西我們在程序中怎么用呢?幸運的是,二叉堆可以用一個簡單的一維數(shù)組來存儲,如下圖所示。

假設一個元素的位置是n(第一個元素的位置為1,而不是通常數(shù)組的第一個索引0),那么它兩個子節(jié)點分別是 n × 2 和 n × 2 + 1 ,父節(jié)點是n除以2取整。比如第3個元素(例中是20)的兩個子節(jié)點位置是6和7(空),父節(jié)點位置是1。

三種操作

對于二叉堆我們通常有三種操作:添加、刪除和修改元素:

* 添加元素

首先把要添加的元素加到數(shù)組的末尾,然后和它的父節(jié)點(位置為當前位置減去1再除以2取整(k-1)/2,比如第4個元素的父節(jié)點位置是1,第7個元素的父節(jié)點位置是3)比較,如果新元素比父節(jié)點元素大則交換這兩個元素,然后再和新位置的父節(jié)點比較,直到它的父節(jié)點不再比它小,或者已經到達頂端,即第1的位置。

* 刪除元素

刪除元素的過程類似,只不過添加元素是"向上冒",而刪除元素是"向下沉":刪除位置1的元素,把最后一個元素移到最前面,然后和它的兩個子節(jié)點比較,如果兩個子節(jié)點中較大的子節(jié)點大于此頂點,就將它們交換,直到兩個子節(jié)點都比此頂點小。

計算兩個子節(jié)點的位置的公式:左子節(jié)點:2K+1、右子節(jié)點:2K+2(注:這里針對的是根節(jié)點為零的情況,若根為1,則左右分別為2K與2K+1。

比如頂點為0,那么它的左右子節(jié)點分別為1和2位置,如果頂點為1,那么 1的左右兩個子節(jié)點即為3,4.以此類推

* 修改元素

和添加元素完全一樣的"向上冒"過程,只是要注意被修改的元素在二叉堆中的位置。

可以看出,使用二叉堆只需很少的幾步就可以完成排序,很大程度上提高了尋路速度。

在C++的STL中提供了優(yōu)先隊列,定義方式為priority_queuepriq;默認為每一次彈出隊列中最大的元素,與二叉堆性質相似,很多時候可以直接當作二叉堆使用。

當然,也可以直接自己寫一個C++的類模板,以下是完整代碼:

#include

const int MAXN = 11111;

int n, a[MAXN], ans = 0;

//以下兩個是自定義校驗函數(shù),mincmp是小根堆所需要的,而maxcmp就是大根堆所需要的了,

inline bool mincmp(const int &x, const int &y)

{ return x < y; }

inline bool maxcmp(const int &x, const int &y)

{ return x > y; }

//定義,第一個關鍵字為堆的大小,第二關鍵字為自定義校驗類型

template

class Heap

{

private:

int a[N], n;//n表示當前元素的個數(shù),同時也是最后一個元素的下一個指針

public:

inline Heap() { clear(); }

inline void clear() { n = 0; }//清空

inline void push(int x)//插入操作

{

int i;

n++;//元素個數(shù)相加

for(i = n - 1; i > 0; i = (i - 1) >> 1)//把這個元素和根節(jié)點比較并交換

{

if(cmp(x, a[(i - 1) >> 1]))

a[i] = a[(i - 1) >> 1];

else break;

}

a[i] = x;

}

inline void pop()//彈出操作,如果需要在彈出的同時返回總根節(jié)點,把void改成int,并加上下面的兩行被注釋部分

{

int tmp, i;

n--;

//int x = a[0];

for(i = 0; (i << 1) + 1 < n; i = tmp)

{

//比較左右子樹中更優(yōu)的一個交換(對于小根堆就是較小的那個,大根堆不解釋……)

tmp = ((i << 1) + 2 < n && cmp(a[(i << 1) + 2], a[(i << 1) + 1])) ? (i << 1) + 2 : (i << 1) + 1;

if(cmp(a[tmp], a[n]))

a[i] = a[tmp];

else

break;

}

a[i] = a[n];

//return x;

}

inline int top() { return a[0]; }//返回堆頂元素

inline bool empty() { return !n; }//判斷堆是否為空

};

Heap< MAXN, maxcmp > h;//定義一個堆,這里定義的是大根堆,如果要使用小根堆,把第二關鍵字換成上面的mincmp就可以了

int main()

{

scanf("%d", &n);

for (int i = 1; i <= n; i++)

{

scanf("%d", a + i);

h.push(a[i]);//壓入堆中

}

for (int i = 1; i <= n; i++)

{

printf("%d ", h.top());//從大到小輸出

h.pop();

}

return 0;

}

二叉堆存儲常見問題

二叉堆存儲文獻

一種基于有序二叉樹的變量池的設計和應用 一種基于有序二叉樹的變量池的設計和應用

格式:pdf

大?。?span id="novia7m" class="single-tag-height">71KB

頁數(shù): 4頁

評分: 4.8

分層模式在軟件開發(fā)中有著廣泛的應用,必然使各層之間產生頻繁的數(shù)據(jù)交互,從而導致軟件性能大大下降。針對上述問題,本文提出一種基于有序二叉樹的變量池的解決方案,軟件的配置信息以及各層之間的交互數(shù)據(jù)保存在變量池中,對變量的所有操作都基于變量池,通過變量池的使用,既方便了各層之間數(shù)據(jù)交互,也簡化了各層之間的接口設計。基于該方案,本文最后實現(xiàn)了一個銀行自助終端系統(tǒng)。

立即下載
實物期權二叉樹方法在房地產投資決策中的應用 實物期權二叉樹方法在房地產投資決策中的應用

格式:pdf

大小:71KB

頁數(shù): 3頁

評分: 4.6

房地產是我國國民經濟的支柱產業(yè),傳統(tǒng)的凈現(xiàn)值貼現(xiàn)方法不再適合于評估房地產項目的價值。本文將實物期權定價的二叉樹方法運用于房地產項目投資決策,通過對案例的解析來說明該方法較傳統(tǒng)的凈現(xiàn)值貼現(xiàn)方法更適合于房地產項目投資決策。

立即下載

優(yōu)先隊列在信息學競賽中十分常見,在統(tǒng)計問題、最值問題、模擬問題和貪心問題等等類型的題目中,優(yōu)先隊列都有著廣泛的應用。二叉堆是一種常用的優(yōu)先隊列,它編程簡單,效率高,但如果問題需要對兩個優(yōu)先隊列進行合并,二叉堆的效率就無法令人滿意了。本文介紹的左偏樹,可以很好地解決這類問題。

左偏樹的定義和性質

在介紹左偏樹之前,我們先來明確一下優(yōu)先隊列和可并堆的概念。

優(yōu)先隊列,可并堆

優(yōu)先隊列(Priority Queue)是一種抽象數(shù)據(jù)類型(ADT),它是一種容器,里面有一些元素,這些元素也稱為隊列中的節(jié)點(node)。優(yōu)先隊列的節(jié)點至少要包含一種性質:有序性,也就是說任意兩個節(jié)點可以比較大小。為了具體起見我們假設這些節(jié)點中都包含一個鍵值(key),節(jié)點的大小通過比較它們的鍵值而定。優(yōu)先隊列有三個基本的操作:插入節(jié)點(Insert),取得最小節(jié)點(Minimum) 和刪除最小節(jié)點(Delete-Min)。

可并堆(Mergeable Heap)也是一種抽象數(shù)據(jù)類型,它除了支持優(yōu)先隊列的三個基本操作(Insert, Minimum,Delete-Min),還支持一個額外的操作--合并操作:

二叉堆相關推薦
  • 相關百科
  • 相關知識
  • 相關專欄