Linux C 数据结构——二叉树
先放這張圖:
可以看出,樹(shù)是非線(xiàn)性結(jié)構(gòu);
一、樹(shù)的概念
????? 樹(shù)(tree)是n(n>=0)個(gè)節(jié)點(diǎn)的有限集合T,它滿(mǎn)足兩個(gè)條件:
1)有且僅有一個(gè)特定的稱(chēng)為根(root)的節(jié)點(diǎn);
2)其余的節(jié)點(diǎn)可以分為m(m>=0)個(gè)互不相交的有限結(jié)合T1、T2、...、Tm,其中每一個(gè)集合又是一棵樹(shù),并成為其根的子數(shù)(Subtree)。
???? 樹(shù)的邏輯結(jié)構(gòu):樹(shù)中任何節(jié)點(diǎn)都可以有零個(gè)或多個(gè)直接后繼節(jié)點(diǎn)(子節(jié)點(diǎn)),但至多只有一個(gè)直接前驅(qū)節(jié)點(diǎn)(父節(jié)點(diǎn)),根節(jié)點(diǎn)沒(méi)有前驅(qū)節(jié)點(diǎn),葉節(jié)點(diǎn)沒(méi)有后繼節(jié)點(diǎn)。
?度數(shù):一個(gè)節(jié)點(diǎn)的子樹(shù)的個(gè)數(shù)稱(chēng)為該節(jié)點(diǎn)的度數(shù),一棵樹(shù)的度數(shù)是指該樹(shù)中節(jié)點(diǎn)的最大度數(shù);
?層數(shù):節(jié)點(diǎn)的層數(shù)等于父節(jié)點(diǎn)的層數(shù)加一,根節(jié)點(diǎn)的層數(shù)定義為一;
?深度:樹(shù)中節(jié)點(diǎn)層數(shù)的最大值稱(chēng)為該樹(shù)的高度或深度;
?
二、二叉樹(shù)
???????二叉樹(shù)(Binary)是n(n>=0)個(gè)節(jié)點(diǎn)的有限集合,它或者是空集(n=0),或者是由一個(gè)根節(jié)點(diǎn)以及兩棵互不相交的、分別稱(chēng)為左子樹(shù)和右子樹(shù)的二叉樹(shù);二叉樹(shù)是有序樹(shù)。
二叉樹(shù)的性質(zhì):
?
滿(mǎn)二叉樹(shù):深度為k(k>=1)時(shí)2ek-1個(gè)節(jié)點(diǎn)的二叉樹(shù);
完全二叉樹(shù):1)只有最下面兩層有度數(shù)小于2的節(jié)點(diǎn);2)最下面一層的葉節(jié)點(diǎn)集中在最左邊的若干位置上;
滿(mǎn)二叉樹(shù)是完全二叉樹(shù)的一個(gè)特例。
1、二叉樹(shù)的順序存儲(chǔ)結(jié)構(gòu)
?完全二叉樹(shù)節(jié)點(diǎn)的編號(hào)方法是從上到下,從左到右,根節(jié)點(diǎn)為1號(hào)節(jié)點(diǎn)。設(shè)完全二叉樹(shù)的節(jié)點(diǎn)數(shù)為n,某節(jié)點(diǎn)編號(hào)為i :
1)當(dāng)i > 1(不是根節(jié)點(diǎn))時(shí),有父節(jié)點(diǎn),其父節(jié)點(diǎn)編號(hào)為i / 2;
2)當(dāng)2 * i <= n 時(shí),有左子樹(shù),其編號(hào)為2 * i,否則沒(méi)有左子樹(shù),本身是葉節(jié)點(diǎn);
3)當(dāng)2 * i? + 1 < = n時(shí),有右子樹(shù),其編號(hào)為2 * i + 1,否則沒(méi)有右子樹(shù);
如何存儲(chǔ):
有n個(gè)節(jié)點(diǎn)的完全二叉樹(shù)可以用有?n + 1 個(gè)元素的數(shù)組進(jìn)行存儲(chǔ),節(jié)點(diǎn)號(hào)和數(shù)組下標(biāo)一一對(duì)應(yīng),下標(biāo)為零的元素不用。
利用以上特性,可以用下標(biāo)獲得節(jié)點(diǎn)的邏輯關(guān)系。不完全二叉樹(shù)通過(guò)添加虛節(jié)點(diǎn)構(gòu)成完全二叉樹(shù),然后用數(shù)組存儲(chǔ),這要浪費(fèi)一些存儲(chǔ)空間。
?通過(guò)添加非字母字符,構(gòu)成完全二叉樹(shù)。
2、二叉樹(shù)的鏈?zhǔn)酱鎯?chǔ)
1)鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu):
[cpp]?view plaincopy2)鏈?zhǔn)蕉鏄?shù)的創(chuàng)建
鏈?zhǔn)蕉鏄?shù)的創(chuàng)建要借助順序存儲(chǔ),比如下面這個(gè)二叉樹(shù)
?
我們需要通過(guò)添加虛節(jié)點(diǎn)使其成為一個(gè)完全二叉樹(shù),并用大小為n+1的數(shù)組來(lái)表示,如下
data_t a[] = {0,'a','b','c','d','e',0,'f',0,0,'g','h',0,0,'i'}; 因?yàn)楣?jié)點(diǎn)號(hào)與數(shù)組下表是一一對(duì)應(yīng)的,所以我們可以通過(guò)這個(gè)數(shù)組創(chuàng)建一個(gè)鏈?zhǔn)蕉鏄?shù)
?利用遞歸創(chuàng)建一個(gè)二叉樹(shù):
[cpp]?view plaincopy它的遍歷順序:
遞歸不論是在我們創(chuàng)建二叉樹(shù)還是遍歷二叉樹(shù)都起到了很大的作用,至于遞歸,大家可以通過(guò)函數(shù)棧來(lái)理解,函數(shù)在執(zhí)行到 root->lchild = CreateBitree(j, a, n); 這一步時(shí),會(huì)再次調(diào)用CreateBitree()函數(shù),這樣會(huì)在棧區(qū)開(kāi)辟一塊空間,知道遇到終止條件才會(huì)返回,即這片內(nèi)存區(qū)域會(huì)被釋放,函數(shù)執(zhí)行向上回收,直至該二叉樹(shù)被創(chuàng)建,大家可以畫(huà)圖理解一下,有空我會(huì)補(bǔ)上圖;
3、二叉樹(shù)的遍歷
??? 遍歷:沿某條搜索路徑周游二叉樹(shù),對(duì)樹(shù)中的每一個(gè)節(jié)點(diǎn)訪問(wèn)一次且僅訪問(wèn)一次。
???? 由于二叉樹(shù)的遞歸性質(zhì),遍歷算法也是遞歸的。三種基本的遍歷算法如下:
1)先序遍歷:先訪問(wèn)樹(shù)根,再訪問(wèn)左子樹(shù),最后訪問(wèn)右子樹(shù);
2)中序遍歷:先訪問(wèn)左子樹(shù),再訪問(wèn)樹(shù)根,最后訪問(wèn)右子樹(shù);
3)后序遍歷:先訪問(wèn)左子樹(shù),再訪問(wèn)右子樹(shù),最后訪問(wèn)樹(shù)根;
?
先序遍歷算法:
[cpp]?view plaincopy中序遍歷算法:
[cpp]?view plaincopy后序遍歷算法:
[cpp]?view plaincopy我們可以把程序整合一下,寫(xiě)個(gè)測(cè)試程序:
[cpp]?view plaincopy執(zhí)行結(jié)果如下:
[cpp]?view plaincopy總結(jié)
以上是生活随笔為你收集整理的Linux C 数据结构——二叉树的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 某大学渗透实录
- 下一篇: Linux_2.6字符设备驱动实例