6.2 基本操作与存储
二叉樹的存儲(chǔ)
1.順序存儲(chǔ)結(jié)構(gòu)
所謂二叉樹的順序存儲(chǔ),就是用一組連續(xù)的存儲(chǔ)單元存放二叉樹中的結(jié)點(diǎn)。一般是按照二叉樹結(jié)點(diǎn)從上至下、從左到右的順序存儲(chǔ)。
這樣結(jié)點(diǎn)在存儲(chǔ)位置上的前驅(qū)后繼關(guān)系并不一定就是它們?cè)谶壿嬌系泥徑雨P(guān)系,然而只有通過(guò)一些方法確定某結(jié)點(diǎn)在邏輯上的前驅(qū)結(jié)點(diǎn)和后繼結(jié)點(diǎn),這種存儲(chǔ)才有意義。因此,依據(jù)二叉樹的性質(zhì),完全二叉樹和滿二叉樹采用順序存儲(chǔ)比較合適,樹中結(jié)點(diǎn)的序號(hào)可以唯一地反映出結(jié)點(diǎn)之間的邏輯關(guān)系,這樣既能夠最大可能地節(jié)省存儲(chǔ)空間,又可以利用數(shù)組元素的下標(biāo)值確定結(jié)點(diǎn)在二叉樹中的位置,以及結(jié)點(diǎn)之間的關(guān)系。圖6.4 給出的圖6.3(a)所示的完全二叉樹的順序存儲(chǔ)示意圖。
對(duì)于一般的二叉樹,如果仍按從上至下和從左到右的順序?qū)渲械慕Y(jié)點(diǎn)順序存儲(chǔ)在一維數(shù)組中,則數(shù)組元素下標(biāo)之間的關(guān)系不能夠反映二叉樹中結(jié)點(diǎn)之間的邏輯關(guān)系,只有增添一些并不存在的空結(jié)點(diǎn),使之成為一棵完全二叉樹的形式,然后再用一維數(shù)組順序存儲(chǔ)。
如圖6.5 給出了一棵一般二叉樹改造后的完全二叉樹形態(tài)和其順序存儲(chǔ)狀態(tài)示意圖。顯然,這種存儲(chǔ)對(duì)于需增加許多空結(jié)點(diǎn)才能將一棵二叉樹改造成為一棵完全二叉樹的存儲(chǔ)時(shí),會(huì)造成空間的大量浪費(fèi),不宜用順序存儲(chǔ)結(jié)構(gòu)。最壞的情況是右單支樹,如圖6.6 所示,一棵深度為k 的右單支樹,只有k 個(gè)結(jié)點(diǎn),卻需分配2k-1 個(gè)存儲(chǔ)單元。
(c) 單支樹改造后完全二叉樹的順序存儲(chǔ)狀態(tài)圖6.6 右單支二叉樹及其順序存儲(chǔ)示意圖二叉樹的順序存儲(chǔ)表示可描述為:
即將bt 定義為含有MAXNODE 個(gè)elemtype 類型元素的一維數(shù)組。
2.鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)
所謂二叉樹的鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)是指,用鏈表來(lái)表示一棵二叉樹,即用鏈來(lái)指示著元素的邏輯關(guān)系。通常有下面兩種形式。
(1)二叉鏈表存儲(chǔ)
鏈表中每個(gè)結(jié)點(diǎn)由三個(gè)域組成,除了數(shù)據(jù)域外,還有兩個(gè)指針域,分別用來(lái)給出該結(jié)點(diǎn)左孩子和右孩子所在的鏈結(jié)點(diǎn)的存儲(chǔ)地址。結(jié)點(diǎn)的存儲(chǔ)的結(jié)構(gòu)為:
其中,data 域存放某結(jié)點(diǎn)的數(shù)據(jù)信息;lchild 與rchild 分別存放指向左孩子和右孩子的指針,當(dāng)左孩子或右孩子不存在時(shí),相應(yīng)指針域值為空(用符號(hào)∧或NULL 表示)。
圖6.7(a)給出了圖6.3(b)所示的一棵二叉樹的二叉鏈表示。二叉鏈表也可以帶頭結(jié)點(diǎn)的方式存放,如圖6.7(b)所示。
(2)三叉鏈表存儲(chǔ)
每個(gè)結(jié)點(diǎn)由四個(gè)域組成,具體結(jié)構(gòu)為:
其中,data、lchild 以及rchild 三個(gè)域的意義同二叉鏈表結(jié)構(gòu);parent 域?yàn)橹赶蛟摻Y(jié)點(diǎn)雙親結(jié)點(diǎn)的指針。這種存儲(chǔ)結(jié)構(gòu)既便于查找孩子結(jié)點(diǎn),又便于查找雙親結(jié)點(diǎn);但是,相對(duì)于二叉鏈表存儲(chǔ)結(jié)構(gòu)而言,它增加了空間開銷。圖6.8 給出了圖6.3(b)所示的一棵二叉樹的三叉鏈表示。
盡管在二叉鏈表中無(wú)法由結(jié)點(diǎn)直接找到其雙親,但由于二叉鏈表結(jié)構(gòu)靈活,操作方便,對(duì)于一般情況的二叉樹,甚至比順序存儲(chǔ)結(jié)構(gòu)還節(jié)省空間。因此,二叉鏈表是最常用的二叉樹存儲(chǔ)方式。本書后面所涉及到的二叉樹的鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)不加特別說(shuō)明的都是指二叉鏈表結(jié)構(gòu)。
二叉樹的二叉鏈表存儲(chǔ)表示可描述為:
即將BiTree 定義為指向二叉鏈表結(jié)點(diǎn)結(jié)構(gòu)的指針類型。
?
二叉樹的基本操作及實(shí)現(xiàn)
1.二叉樹的基本操作
二叉樹的基本操作通常有以下幾種:
(1)Initiate(bt)建立一棵空二叉樹。
(2)Create(x,lbt,rbt)生成一棵以x 為根結(jié)點(diǎn)的數(shù)據(jù)域信息,以二叉樹lbt 和rbt為左子樹和右子樹的二叉樹。
(3)InsertL(bt,x,parent)將數(shù)據(jù)域信息為x 的結(jié)點(diǎn)插入到二叉樹bt 中作為結(jié)點(diǎn)parent 的左孩子結(jié)點(diǎn)。如果結(jié)點(diǎn)parent 原來(lái)有左孩子結(jié)點(diǎn),則將結(jié)點(diǎn)parent 原來(lái)的左孩子結(jié)點(diǎn)作為結(jié)點(diǎn)x 的左孩子結(jié)點(diǎn)。
(4)InsertR(bt,x,parent)將數(shù)據(jù)域信息為x 的結(jié)點(diǎn)插入到二叉樹bt 中作為結(jié)點(diǎn)parent 的右孩子結(jié)點(diǎn)。如果結(jié)點(diǎn)parent 原來(lái)有右孩子結(jié)點(diǎn),則將結(jié)點(diǎn)parent 原來(lái)的右孩子結(jié)點(diǎn)作為結(jié)點(diǎn)x 的右孩子結(jié)點(diǎn)。
(5)DeleteL(bt,parent)在二叉樹bt 中刪除結(jié)點(diǎn)parent 的左子樹。
(6)DeleteR(bt,parent)在二叉樹bt 中刪除結(jié)點(diǎn)parent 的右子樹。
(7)Search(bt,x)在二叉樹bt 中查找數(shù)據(jù)元素x。
(8)Traverse(bt)按某種方式遍歷二叉樹bt 的全部結(jié)點(diǎn)。
2.算法的實(shí)現(xiàn)
算法的實(shí)現(xiàn)依賴于具體的存儲(chǔ)結(jié)構(gòu),當(dāng)二叉樹采用不同的存儲(chǔ)結(jié)構(gòu)時(shí),上述各種操作的實(shí)現(xiàn)算法是不同的。下面討論基于二叉鏈表存儲(chǔ)結(jié)構(gòu)的上述操作的實(shí)現(xiàn)算法。
(1)Initiate(bt)初始建立二叉樹bt,并使bt 指向頭結(jié)點(diǎn)。在二叉樹根結(jié)點(diǎn)前建立頭結(jié)點(diǎn),就如同在單鏈表前建立的頭結(jié)點(diǎn),可以方便后邊的一些操作實(shí)現(xiàn)。
算法6.1
(2)Create(x,lbt,rbt)建立一棵以x 為根結(jié)點(diǎn)的數(shù)據(jù)域信息,以二叉樹lbt 和rbt為左右子樹的二叉樹。
建立成功時(shí)返回所建二叉樹結(jié)點(diǎn)的指針;建立失敗時(shí)返回空指針。
1 BiTree Create(elemtype x,BiTree lbt,BiTree rbt) 2 { 3 /*生成一棵以x 為根結(jié)點(diǎn)的數(shù)據(jù)域值以lbt 和rbt 為左右子樹的二叉樹*/ 4 BiTree p; 5 if ((p=(BiTNode *)malloc(sizeof(BiTNode)))==NULL) return NULL; 6 p->data=x; 7 p->lchild=lbt; 8 p->rchild=rbt; 9 return p; 10 }算法6.2
(3)InsertL(bt,x,parent)
算法6.3
(4)InsertR(bt,x,parent)功能類同于(3),算法略。
(5)DeleteL(bt,parent)在二叉樹bt 中刪除結(jié)點(diǎn)parent 的左子樹。當(dāng)parent 或parent的左孩子結(jié)點(diǎn)為空時(shí)刪除失敗。刪除成功時(shí)返回根結(jié)點(diǎn)指針;刪除失敗時(shí)返回空指針。
算法6.4
(6)DeleteR(bt,parent)功能類同于(5),只是刪除結(jié)點(diǎn)parent 的右子樹。算法略。操作Search(bt,x)實(shí)際是遍歷操作Traverse(bt)的特例,關(guān)于二叉樹的遍歷操作的實(shí)現(xiàn),將在下一節(jié)中重點(diǎn)介紹。
轉(zhuǎn)載于:https://www.cnblogs.com/chunlanse2014/articles/4583458.html
總結(jié)
以上是生活随笔為你收集整理的6.2 基本操作与存储的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: strcpy_s与strcpy对照
- 下一篇: String 字符串对象