国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

基于隊列的任意二叉樹層次問題算法設計

2018-05-07 07:10:29
關鍵詞:二叉樹入隊鏈式

吳 志 福

(石家莊職業(yè)技術學院 組織部,河北 石家莊 050081)

在數(shù)據(jù)結(jié)構(gòu)中,樹是一種用途廣泛的結(jié)構(gòu).二叉樹是每個節(jié)點最多有兩個子樹的樹結(jié)構(gòu).在對任意二叉樹進行存儲的時候,普遍采用鏈式結(jié)構(gòu)存儲數(shù)據(jù),在對鏈式結(jié)構(gòu)存儲的任意二叉樹進行操作的時候,常采用遞歸的方法來實現(xiàn).在求任意二叉樹的層次問題上,也采用遞歸方法來實現(xiàn).但遞歸方式算法復雜且不容易理解.對任意二叉樹的研究發(fā)現(xiàn),對于涉及到任意二叉樹層次的計算,由于其結(jié)構(gòu)的特殊性,完全可以使用比較容易理解的隊列來解決.

1 二叉樹的存儲結(jié)構(gòu)

二叉樹的存儲方式有順序結(jié)構(gòu)和鏈式結(jié)構(gòu)兩種[1].在任意二叉樹的順序存儲結(jié)構(gòu)中,采用數(shù)組存放任意二叉樹的節(jié)點.二叉樹層次和數(shù)組下標表示為:

M=log2(n+1).

其中,M表示二叉樹層次,n表示數(shù)組的最大下標.

圖1為任意二叉樹結(jié)構(gòu)示意圖.采用順序結(jié)構(gòu)存儲時,利用數(shù)組存儲的結(jié)果見表1.

圖1 任意二叉樹結(jié)構(gòu)示意圖

數(shù)組下標存放節(jié)點數(shù)組下標存放節(jié)點數(shù)組下標存放節(jié)點1B14B47B52B25空8B63B36空??

從表1可以看出,雖然采用順序結(jié)構(gòu)存儲的任意二叉樹可以利用公式很方便地計算出任意二叉樹層次,但是利用數(shù)組存儲數(shù)據(jù)時,會存在大量空節(jié)點,造成空間的浪費,因此任意二叉樹存儲一般不采用順序結(jié)構(gòu)而采用鏈式結(jié)構(gòu).

在采用鏈式結(jié)構(gòu)存儲任意二叉樹時,由于二叉樹的每個結(jié)點最多有左右兩個孩子,因此,每個結(jié)點除了存儲自身的數(shù)據(jù)外,還設置兩個指針分別指向左孩子、右孩子的結(jié)點.鏈式結(jié)構(gòu)任意二叉樹存儲結(jié)點示意圖見圖2.

左孩子地址節(jié)點數(shù)據(jù)右孩子地址

圖2鏈式結(jié)構(gòu)任意二叉樹存儲結(jié)點示意圖

對于圖1所示任意二叉樹,其B1-B4節(jié)點的鏈式存儲結(jié)構(gòu)如圖3所示.

(1)B1節(jié)點存儲結(jié)構(gòu)

(2)B2節(jié)點存儲結(jié)構(gòu)

(3)B3節(jié)點存儲結(jié)構(gòu)

(4)B4節(jié)點存儲結(jié)構(gòu)

圖3任意二叉樹節(jié)點的鏈式存儲結(jié)構(gòu)示意圖

鏈式結(jié)構(gòu)存儲保留了任意二叉樹的結(jié)構(gòu),且不存在空間浪費問題,但是無法通過公式來計算二叉樹的層次,只能采用遞歸的方式遍歷二叉樹進而求得層次.由于遞歸涉及到調(diào)用時空間的開辟、現(xiàn)場的保存、參數(shù)的傳遞等問題,算法較難理解,因此需要尋找合適的算法求鏈式結(jié)構(gòu)任意二叉樹的層次.

2 算法設計

2.1 設計思路

在計算鏈式結(jié)構(gòu)存儲的任意二叉樹層次的過程中,需要遍歷整個任意二叉樹,即需要處理多個相同結(jié)構(gòu)的數(shù)據(jù),為了便于數(shù)據(jù)的處理,減少空間的浪費,采用隊列結(jié)構(gòu)來實現(xiàn)層次算法.在使用隊列求任意二叉樹層次時,算法中僅增加了一個隊列和一個順序結(jié)構(gòu)的數(shù)組[2],沒有增加太多的空間,但卻減少了遞歸調(diào)用時空間的開辟.

隊列是常用的一種數(shù)據(jù)結(jié)構(gòu),其特點是“先進先出”,即刪除操作只允許在隊列的前端進行,插入操作只在隊列的后端進行,進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭,所以先進入隊列的元素總是先被刪除的.利用隊列這一特點,對采用鏈式結(jié)構(gòu)存儲的任意二叉樹按照層次關系將其節(jié)點進行入隊和出隊操作,將其從邏輯關系上轉(zhuǎn)變?yōu)榫€性結(jié)構(gòu),在轉(zhuǎn)變的過程中,利用輔助數(shù)組記錄任意二叉樹的層次.當轉(zhuǎn)變完成時,任意二叉樹的層次也就得以保存.

在用隊列實現(xiàn)二叉樹的層次問題時,讓根節(jié)點首先入隊,繼續(xù)進行操作的時候,節(jié)點出隊的同時如果它的左孩子或右孩子不為空,循環(huán)操作將其入隊.這樣,每一層的節(jié)點將按照先左后右的順序入隊.由于節(jié)點的地址之間沒有固定的線性關系,因此利用一個輔助數(shù)組來記住每一層的最左節(jié)點在隊列中的位置,在隊列不為空的時候?qū)㈥狀^元素出隊,同時重復前面的入隊操作.由于節(jié)點在不斷地入隊和出隊,所以記錄節(jié)點位置的輔助數(shù)組的長度要不小于二叉樹的最大寬度.

2.2 設計程序

在算法設計過程中,隊列采用結(jié)構(gòu)體來表示,結(jié)構(gòu)為:

struct queue /* 隊列*/

{

struct bitree *elem[MAXSIZE]; /* bitree為鏈式存儲的任意二叉樹的節(jié)點類型*/

int front,rear; /*頭指針和尾指針*/

}

為了節(jié)省空間,減少系統(tǒng)的空間開銷,隊列中只保存了指向鏈式存儲的任意二叉樹的節(jié)點的指針,而沒有保存其數(shù)據(jù).

對圖1所示任意二叉樹進行遍歷的過程如下:

根節(jié)點B1首先入隊.此時隊列中的數(shù)據(jù)如圖4所示.

0節(jié)點B11

圖4根節(jié)點B1入隊后隊列示意圖

此時,輔助數(shù)組fuzhu[ ]中保存元素全部初始化為0,輔助數(shù)組下標j初始化為0,樹的層次數(shù)k標記為0.為了標記是否是最左節(jié)點入隊,初始化flag為0.

隨后,在隊列不為空的情況下進入隊列的循環(huán)操作.

(1)隊首元素B1出隊,保存到變量P中.執(zhí)行出隊操作后,圖4中數(shù)據(jù)變化見圖5所示.

1節(jié)點B11

圖5根節(jié)點B1出隊后隊列示意圖

(2)判斷p是否有左孩子或右孩子,且其左、右孩子是否為下一層的最左節(jié)點,如果是最左節(jié)點,則j增加1,k增加1,將下一層最左節(jié)點地址寫入fuzhu[ ].

在圖1中,節(jié)點B1有左孩子且其左孩子是下一層的最左節(jié)點,因此將j增加1,此時j的值為1,為fuzhu[j]寫入下一層最左節(jié)點的值,此值即為圖4中最右邊的數(shù)據(jù),即fuzhi[1].由于下一層的最左節(jié)點已經(jīng)入隊,因此更改flag值為1.

(3)判斷已經(jīng)出隊節(jié)點是否為本層的最右節(jié)點,若是,則隊列中首元素為下一層的最左節(jié)點,后續(xù)將開始下一層的出隊和下下層的入隊,因此更改flag值為0.

(4)判斷p的左孩子是否不為空,如果不為空,則左孩子入隊.

(5)判斷p的右孩子是否不為空,如果不為空,則右孩子入隊.

(6)繼續(xù)返回開始步驟進行循環(huán),直至隊列為空.

對于圖1的任意二叉樹,其遍歷至第三層的過程中,隊列和對應輔助數(shù)組的變化過程如圖6所示.

從圖6中可以看出,隨著任意二叉樹節(jié)點的入隊和出隊,輔助數(shù)組中記錄了每一層節(jié)點的最左節(jié)點,flag值記錄了任意二叉樹的層次.當循環(huán)結(jié)束時,flag的值就是任意二叉樹的層次.

3 算法實現(xiàn)

算法中循環(huán)部分的C語言實現(xiàn)代碼如下:

int cc(struct bitree *root)

/*求任意二叉樹的最大層次數(shù),二叉樹采用鏈式存儲結(jié)構(gòu)*/

{

int fuzhi={0},j=0,k=1,flag=0;

struct queue *q;

struct bitree *p

inistilize(q);/*隊列初始化*/

p=root;

enterque(q,p);/*根節(jié)點入隊*/

while(! isempty(q)) /*隊列非空*/

{

p=deleteque(q); /*隊首元素出隊*/

if (( p->lchild!=NULL ||p->rchild!=NULL) &&flag= =0)

/* flag 為0時,下一層還沒有節(jié)點入隊, 已經(jīng)出隊節(jié)點的孩子節(jié)點為下一層的最左節(jié)點*/

{

j++; /*輔助數(shù)組下標加1*/

flag=1;

/*將標志變?yōu)?,表示下一層已經(jīng)有節(jié)點入隊 */

fuzhi[j]=q->rear

/*下一層的最左節(jié)點的位置*/;

k++; /*層次數(shù)加1*/

}

if (q->front= =a[j])

/*已經(jīng)出隊節(jié)點為本層的最右節(jié)點*/

flag=0;

if (p->lchild!=NULL)

/*左孩子節(jié)點入隊*/

enterqueue(q,p->lchild);

if(p->rchild!=NULL)

/*右孩子節(jié)點入隊*/

enterqueue(q,p->rchild);

}

return(k); /*返回最大層次數(shù)*/

}

在此算法的具體設計中,對任意二叉樹采用了鏈式存儲結(jié)構(gòu),隊列采用了順序結(jié)構(gòu)的循環(huán)隊列,并且規(guī)定,當隊列中只剩余一個空間時,隊列滿,即“尾指針+1”,對初始化的隊列長度求余等于“頭指針”時,隊列滿.隊列的出隊、入隊、初始化等問題和循環(huán)隊列的相同.文中不再給出樹、隊列的數(shù)據(jù)結(jié)構(gòu)源代碼和隊列的出隊、入隊、初始化等的代碼.

圖6 算法過程隊列及輔助數(shù)組變化示意圖

4 結(jié)語

本算法的源程序已經(jīng)在Visual C++6.0中通過調(diào)試,能解決求二叉樹的最大層次問題.在解決實際問題的過程中,可以根據(jù)需要將程序加以改變,從而實現(xiàn)和層次相關問題的求解,如二叉樹的樹形輸出、二叉樹的最大寬度即層上節(jié)點的最大個數(shù)等問題,均可采用此算法.

參考文獻:

[1] 嚴蔚敏,吳偉民.數(shù)據(jù)結(jié)構(gòu):C語言版[M].北京:清華大學出版社,1997:126-127.

[2] 朱雅莉,李肯立.DNA計算機中基于順序存儲方式的二叉樹數(shù)據(jù)結(jié)構(gòu)[J].計算機應用,2008,28(6):1591-1594.

猜你喜歡
二叉樹入隊鏈式
CSP真題——二叉樹
電腦報(2022年37期)2022-09-28 05:31:07
今天我入隊——入隊儀式
少先隊活動(2022年5期)2022-06-06 03:45:02
二叉樹創(chuàng)建方法
1+1我們這樣學隊章:我們的入隊誓詞
少先隊活動(2020年7期)2020-08-14 01:17:50
今天我入隊了
入隊風波
鏈式STATCOM內(nèi)部H橋直流側(cè)電壓均衡控制策略
黑龍江電力(2017年1期)2017-05-17 04:25:05
一種由層次遍歷和其它遍歷構(gòu)造二叉樹的新算法
10kV鏈式STATCOM的研究與設計
電測與儀表(2015年4期)2015-04-12 00:43:08
鏈式D-STATCOM直流電壓分層協(xié)調(diào)控制策略
電測與儀表(2015年4期)2015-04-12 00:43:08
江都市| 瓮安县| 平遥县| 平顺县| 民乐县| 霍山县| 临城县| 济南市| 裕民县| 卢湾区| 潮安县| 叶城县| 马公市| 淮安市| 娄底市| 叙永县| 青神县| 新兴县| 治县。| 阳新县| 山东省| 平原县| 德清县| 镶黄旗| 工布江达县| 汽车| 钟山县| 灌云县| 宜宾市| 长葛市| 读书| 广东省| 红河县| 平遥县| 宿松县| 桐柏县| 富宁县| 罗江县| 南城县| 宁海县| 灵丘县|