【數(shù)據(jù)結(jié)構(gòu)】樹的定義和樹的三種存儲(chǔ)結(jié)構(gòu)

之前談?wù)摰逆湵斫嬗场㈥?duì)列都是一對(duì)一的線性結(jié)構(gòu),那么一對(duì)多的情況如何處理呢睬关?“樹”有效的解決了這種一對(duì)多的數(shù)據(jù)結(jié)構(gòu)關(guān)系矮燎。

一、樹的定義

1.樹的定義

樹(Tree)是n(n>=0)個(gè)結(jié)點(diǎn)的有限集转砖。n=0時(shí)稱為空樹须鼎。在任意一顆非空樹中:

  1. 有且僅有一個(gè)特定的稱為根(root)的結(jié)點(diǎn)
  2. 當(dāng)n>1時(shí)府蔗,其余結(jié)點(diǎn)可分為m(m>0)個(gè)互補(bǔ)交互的有限集T1莉兰、T2...Tm,其中每一個(gè)集合本身又是一棵樹礁竞,并稱為根的子樹(SubTree)糖荒。
    Tree
2.樹的特點(diǎn)
  • n>0時(shí),根節(jié)點(diǎn)是唯一的模捂,不可能存在多個(gè)根節(jié)點(diǎn)捶朵。數(shù)據(jù)結(jié)構(gòu)中的樹只有一個(gè)根節(jié)點(diǎn)蜘矢。
  • m>0時(shí),子樹的個(gè)數(shù)沒有限制综看,但他們一定是互不相交的品腹。
3.結(jié)點(diǎn)的分類
  • 結(jié)點(diǎn):樹的結(jié)點(diǎn)包含一個(gè)數(shù)據(jù)元素和若干指向其子樹的分支
  • 結(jié)點(diǎn)的度(Degree):結(jié)點(diǎn)擁有的子樹红碑。
  • 葉子結(jié)點(diǎn)(Leaf)/終端結(jié)點(diǎn):度為0的結(jié)點(diǎn)舞吭。
  • 分支結(jié)點(diǎn)/非終端結(jié)點(diǎn):度不為0的結(jié)點(diǎn)。
  • 內(nèi)部結(jié)點(diǎn):除根節(jié)點(diǎn)以外析珊,分支結(jié)點(diǎn)也稱為內(nèi)部結(jié)點(diǎn)羡鸥。
  • 樹的度:樹內(nèi)各結(jié)點(diǎn)的度的最大值
    結(jié)點(diǎn)的分類
4.結(jié)點(diǎn)之間的關(guān)系
  • 孩子(Child)和雙親(Parent):結(jié)點(diǎn)的子樹的根忠寻,相應(yīng)的惧浴,該結(jié)點(diǎn)稱為孩子的雙親。(注意是雙親奕剃,不是單親)
  • 兄弟(sibling):同一個(gè)雙親的孩子之間互稱兄弟衷旅。
  • 結(jié)點(diǎn)的祖先:從根結(jié)點(diǎn)到該結(jié)點(diǎn)所經(jīng)過分支上的所有結(jié)點(diǎn)
  • 子孫:以某結(jié)點(diǎn)為根的子樹中的任一結(jié)點(diǎn)都稱為該節(jié)點(diǎn)的子孫纵朋。
  • 無序樹和有序樹:如果將樹中結(jié)點(diǎn)的各子樹看成從左至右是有次序的柿顶,不能互換的,則稱該數(shù)為有序樹操软,否則為無序樹嘁锯。
  • 森林(fores):m(m>=0)棵互不相較的樹的集合。

二寺鸥、樹的存儲(chǔ)結(jié)構(gòu)

對(duì)于存儲(chǔ)結(jié)構(gòu),可能會(huì)聯(lián)想到前面的順序存儲(chǔ)和鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)品山。但是對(duì)于數(shù)這種可能會(huì)有很多孩子的特殊數(shù)據(jù)結(jié)構(gòu)胆建,只用順序存儲(chǔ)結(jié)構(gòu)或者鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)很那實(shí)現(xiàn),那么可以將這兩者結(jié)合肘交,產(chǎn)生主要的三種存儲(chǔ)結(jié)構(gòu)表示法:雙親表示法笆载、孩子表示法、孩子兄弟表示法涯呻。

1.雙親表示法

雙親表示法定義

假設(shè)以一組連續(xù)空間存儲(chǔ)數(shù)的結(jié)點(diǎn)凉驻,同時(shí)在每個(gè)結(jié)點(diǎn)中,附設(shè)一個(gè)指示器指示其雙親結(jié)點(diǎn)到鏈表中的位置复罐。

雙親表示的結(jié)點(diǎn)結(jié)構(gòu)
data(數(shù)據(jù)域) parent(指針域)
存儲(chǔ)結(jié)點(diǎn)的數(shù)據(jù)信息 存儲(chǔ)該結(jié)點(diǎn)的雙親所在數(shù)組中的下標(biāo)
代碼實(shí)現(xiàn)雙親表示法
/* 樹的雙親表法結(jié)點(diǎn)結(jié)構(gòu)定義*/
#define MAX_TREE_SIZE 100
typedef int  ElemeType;

typedef struct PTNode{ // 結(jié)點(diǎn)結(jié)構(gòu)
    ElemeType data; //結(jié)點(diǎn)數(shù)據(jù)
    int parent;    // 雙親位置
}PTNode;

typedef struct { // 樹結(jié)構(gòu)
    PTNode nodes[MAX_TREE_SIZE];   // 結(jié)點(diǎn)數(shù)組
    int r; // 根的位置
    int n; // 結(jié)點(diǎn)數(shù)
}PTree;
雙親表示法的特點(diǎn)
  • 由于根結(jié)點(diǎn)是沒有雙親的涝登,約定根結(jié)點(diǎn)的位置位置域?yàn)?1.
  • 根據(jù)結(jié)點(diǎn)的parent指針很容易找到它的雙親結(jié)點(diǎn)。所用時(shí)間復(fù)雜度為O(1)效诅,直到parent為-1時(shí)胀滚,表示找到了樹結(jié)點(diǎn)的根趟济。
  • 缺點(diǎn):如果要找到孩子結(jié)點(diǎn),需要遍歷整個(gè)結(jié)構(gòu)才行咽笼。

2.孩子表示法

孩子表示法定義

把每個(gè)結(jié)點(diǎn)的孩子結(jié)點(diǎn)排列起來顷编,以單鏈表作為存儲(chǔ)結(jié)構(gòu),則n個(gè)結(jié)點(diǎn)有n個(gè)孩子鏈表剑刑,如果是葉子結(jié)點(diǎn)則此單鏈表為空媳纬。然后n個(gè)頭指針又組成一個(gè)線性表,采用順序存儲(chǔ)結(jié)構(gòu)施掏,存放進(jìn)一個(gè)一維數(shù)組中钮惠。

孩子表示法

孩子表示法的結(jié)點(diǎn)結(jié)構(gòu)

孩子表示法有兩種結(jié)點(diǎn)結(jié)構(gòu):孩子鏈表的孩子結(jié)點(diǎn)表頭數(shù)組的表頭結(jié)點(diǎn)

  • 孩子鏈表的孩子結(jié)點(diǎn)
child(數(shù)據(jù)域) next(指針域)
存儲(chǔ)某個(gè)結(jié)點(diǎn)在表頭數(shù)組中的下標(biāo) 存儲(chǔ)指向某結(jié)點(diǎn)的下一個(gè)孩子結(jié)點(diǎn)的指針
  • 表頭數(shù)組的表頭結(jié)點(diǎn)
data(數(shù)據(jù)域) firstchild(頭指針域)
存儲(chǔ)某個(gè)結(jié)點(diǎn)的數(shù)據(jù)信息 存儲(chǔ)該結(jié)點(diǎn)的孩子鏈表的頭指針
代碼實(shí)現(xiàn)孩子表示法
/* 樹的孩子表示法結(jié)構(gòu)定義*/
#define MAX_TREE_SIZE 100
typedef int  ElemeType;

typedef struct CTNode{  // 孩子結(jié)點(diǎn)
    int child; // 孩子結(jié)點(diǎn)的下標(biāo)
    struct CTNode * next; // 指向下一結(jié)點(diǎn)的指針
}*ChildPtr;

typedef struct {  // 表頭結(jié)構(gòu)
    ElemeType data; // 存放在數(shù)中的結(jié)點(diǎn)數(shù)據(jù)
    ChildPtr firstchild; // 指向第一個(gè)孩子的指針
}CTBox;

typedef struct {  // 樹結(jié)構(gòu)
    CTBox nodes[MAX_TREE_SIZE]; // 結(jié)點(diǎn)數(shù)組
    int r;  // 根的位置
    int n;  // 結(jié)點(diǎn)樹
}CTree;
雙親孩子表示法定義

對(duì)于孩子表示法,查找某個(gè)結(jié)點(diǎn)的某個(gè)孩子其监,或者找某個(gè)結(jié)點(diǎn)的兄弟萌腿,只需要查找這個(gè)結(jié)點(diǎn)的孩子單鏈表即可。但是當(dāng)要尋找某個(gè)結(jié)點(diǎn)的雙親時(shí)抖苦,就不是那么方便了毁菱。所以可以將雙親表示法和孩子表示法結(jié)合,形成雙親孩子表示法锌历。


show code

/* 樹的雙親孩子表示法結(jié)構(gòu)定義*/
#define MAX_TREE_SIZE 100
typedef int  ElemeType;

typedef struct CTNode{  // 孩子結(jié)點(diǎn)
    int child;  // 孩子結(jié)點(diǎn)的下標(biāo)
    struct CTNode * next;  // 指向下一結(jié)點(diǎn)的指針
}*ChildPtr;

typedef struct {  // 表頭結(jié)構(gòu)
    ElemeType data;  // 存放在數(shù)中的結(jié)點(diǎn)數(shù)據(jù)
    int parent;      // 存放雙親的下標(biāo)
    ChildPtr firstchild;  // 指向第一個(gè)孩子的指針
}CTBox;

typedef struct {  // 樹結(jié)構(gòu)
    CTBox nodes[MAX_TREE_SIZE]; // 結(jié)點(diǎn)數(shù)組
    int r;  // 根的位置
    int n;  // 結(jié)點(diǎn)樹
}CTree;

3.孩子兄弟表示法

孩子兄弟表示法定義

任意一棵樹贮庞,它的結(jié)點(diǎn)的第一個(gè)孩子如果存在就是唯一的,它的右兄弟存在也是唯一的究西。因此窗慎,設(shè)置兩個(gè)指針,分別指向該結(jié)點(diǎn)的第一個(gè)孩子和此結(jié)點(diǎn)的右兄弟卤材。

孩子兄弟表示法的結(jié)點(diǎn)結(jié)構(gòu)
data(數(shù)據(jù)域) firstchild(指針域) rightsib(指針域)
存儲(chǔ)結(jié)點(diǎn)的數(shù)據(jù)信息 存儲(chǔ)該結(jié)點(diǎn)的第一個(gè)孩子的存儲(chǔ)地址 存儲(chǔ)該結(jié)點(diǎn)的右兄弟結(jié)點(diǎn)的存儲(chǔ)地址
代碼實(shí)現(xiàn)孩子兄弟表示法
/* 樹的孩子兄弟表示法結(jié)構(gòu)定義*/
#define MAX_TREE_SIZE 100
typedef int  ElemeType;

typedef struct CSNode{
    ElemeType data;
    struct CSNode * firstchild;
    struct CSNode * rightsib;
    
}CSNode, *CSTree;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末遮斥,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子扇丛,更是在濱河造成了極大的恐慌术吗,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件帆精,死亡現(xiàn)場(chǎng)離奇詭異较屿,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)卓练,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門隘蝎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人襟企,你說我怎么就攤上這事嘱么。” “怎么了顽悼?”我有些...
    開封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵拱撵,是天一觀的道長(zhǎng)辉川。 經(jīng)常有香客問我,道長(zhǎng)拴测,這世上最難降的妖魔是什么乓旗? 我笑而不...
    開封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮集索,結(jié)果婚禮上屿愚,老公的妹妹穿的比我還像新娘。我一直安慰自己务荆,他們只是感情好妆距,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著函匕,像睡著了一般娱据。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上盅惜,一...
    開封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天中剩,我揣著相機(jī)與錄音,去河邊找鬼抒寂。 笑死结啼,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的屈芜。 我是一名探鬼主播郊愧,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼井佑!你這毒婦竟也來了属铁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤躬翁,失蹤者是張志新(化名)和其女友劉穎焦蘑,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體姆另,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡喇肋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年坟乾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了迹辐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡甚侣,死狀恐怖明吩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情殷费,我是刑警寧澤印荔,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布低葫,位于F島的核電站,受9級(jí)特大地震影響仍律,放射性物質(zhì)發(fā)生泄漏嘿悬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一水泉、第九天 我趴在偏房一處隱蔽的房頂上張望善涨。 院中可真熱鬧,春花似錦草则、人聲如沸钢拧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)源内。三九已至,卻和暖如春份殿,著一層夾襖步出監(jiān)牢的瞬間膜钓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工伯铣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留呻此,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓腔寡,卻偏偏與公主長(zhǎng)得像焚鲜,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子放前,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容