欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)系列之樹(shù)的概念結(jié)構(gòu)和常見(jiàn)表示方法

 更新時(shí)間:2022年02月24日 16:18:26   作者:檸檬葉子C  
本章將正式開(kāi)啟數(shù)據(jù)結(jié)構(gòu)中?“樹(shù)”?部分的講解,本章將介紹樹(shù)的概念和結(jié)構(gòu),以及樹(shù)的表示方法,感興趣的朋友進(jìn)來(lái)看看吧

0x00 樹(shù)的概念

?? 樹(shù)是一種非線(xiàn)性的數(shù)據(jù)結(jié)構(gòu),它是由 n(n >= 0)個(gè)有限節(jié)點(diǎn)組成的一個(gè)具有層次關(guān)系的集合。

? 那么為什么叫 "樹(shù)" 呢?

?? 我們之所以把它成為 "樹(shù)",是因?yàn)樗芟裎覀儸F(xiàn)實(shí)生活中的樹(shù)。只是它是倒過(guò)來(lái)的,根朝上葉子朝下。

0x01 樹(shù)的結(jié)構(gòu)

① 有一個(gè)特殊的節(jié)點(diǎn),成為根節(jié)點(diǎn),根節(jié)點(diǎn)不存在前驅(qū)節(jié)點(diǎn)。

② 除根節(jié)點(diǎn)外,其余節(jié)點(diǎn)被分成 M(M>0) 個(gè)互不相交的集合 T1、T2、……、Tm,期中沒(méi)一個(gè)集合 Ti(1 <= i <= m) 又是一顆結(jié)構(gòu)于樹(shù)類(lèi)似的字?jǐn)?shù)。每顆子樹(shù)的節(jié)點(diǎn)有且只有一個(gè)前驅(qū),可以有0個(gè)或多個(gè)后繼。

③ 因此,樹(shù)是遞歸定義的。因?yàn)槿魏螛?shù)都會(huì)被分成根和子樹(shù)。

??注意:樹(shù)型結(jié)構(gòu)中,子樹(shù)之間不能有交集,否則就不是樹(shù)形結(jié)構(gòu)。

0x02 樹(shù)的相關(guān)概念

??  節(jié)點(diǎn)的度:一個(gè)節(jié)點(diǎn)含有的子樹(shù)的個(gè)數(shù)稱(chēng)為該節(jié)點(diǎn)的度。 比如上圖中,A的度為6。

?? 葉子結(jié)點(diǎn):又稱(chēng)終端節(jié)點(diǎn),度為0的節(jié)點(diǎn)稱(chēng)為葉子結(jié)點(diǎn)。 比如上圖中,BCHIPQ等節(jié)點(diǎn)就是葉子結(jié)點(diǎn),因?yàn)樗鼈兊亩葹?。

? 分支節(jié)點(diǎn):又稱(chēng)非終端節(jié)點(diǎn),度不為0的節(jié)點(diǎn)稱(chēng)為分支節(jié)點(diǎn)。 比如上圖中,DEFG等節(jié)點(diǎn)就是分支節(jié)點(diǎn),因?yàn)樗麄兊亩炔粸?。

?? 父節(jié)點(diǎn):又稱(chēng)雙親結(jié)點(diǎn),若一個(gè)節(jié)點(diǎn)有子節(jié)點(diǎn),則這個(gè)節(jié)點(diǎn)稱(chēng)作其子節(jié)點(diǎn)的父節(jié)點(diǎn)。 比如上圖中,A是B的父節(jié)點(diǎn)。

?? 子節(jié)點(diǎn):又稱(chēng)孩子節(jié)點(diǎn),若一個(gè)節(jié)點(diǎn)有根節(jié)點(diǎn),則稱(chēng)為該節(jié)點(diǎn)的子節(jié)點(diǎn)。 如上圖,B是A的子節(jié)點(diǎn)。

?? 兄弟節(jié)點(diǎn):具有相同父節(jié)點(diǎn)的節(jié)點(diǎn)互相稱(chēng)為兄弟節(jié)點(diǎn)。 同一個(gè)父親生的才算。如上圖,B和C是兄弟節(jié)點(diǎn),它們的父節(jié)點(diǎn)都是A。

?? 樹(shù)的度:一棵樹(shù)中最大的節(jié)點(diǎn)的度稱(chēng)為樹(shù)的度。 如上圖,最大的節(jié)點(diǎn)是A,有6個(gè)子樹(shù),故A的度為6,所以樹(shù)的度為6。

?? 節(jié)點(diǎn)的層次:從根開(kāi)始定義起,根為第1層,根的子節(jié)點(diǎn)為第2層,以此類(lèi)推。 也有將根定義為第0層,根的子節(jié)點(diǎn)為第1層的。但是我們建議還是使用根為第1層來(lái)定義比較好。

?? 樹(shù)的高度:又稱(chēng)樹(shù)的深度,樹(shù)中節(jié)點(diǎn)的最大層次。 如上圖,樹(shù)的高度為 4。

??‍♂? 堂兄弟節(jié)點(diǎn):父節(jié)點(diǎn)在同一層的節(jié)點(diǎn),它們互為堂兄弟。如上圖,H 和 I 互為堂兄弟。

?? 節(jié)點(diǎn)的祖先:從根到該節(jié)點(diǎn)所經(jīng)分支上的所有節(jié)點(diǎn)。 如上圖·,A是所有節(jié)點(diǎn)的祖先。

??‍??‍?? 子孫:以某節(jié)點(diǎn)為根的子樹(shù)中任一節(jié)點(diǎn)都稱(chēng)為該節(jié)點(diǎn)的子孫。 如上圖,所有節(jié)點(diǎn)都是A的子孫。

?? 森林:由 m(m > 0) 棵互不相交的樹(shù)的集合稱(chēng)為森林。 比如并查集,多個(gè)樹(shù)構(gòu)成森林。

0x02 樹(shù)的表示

? 以前學(xué)單鏈表時(shí)只有一個(gè)指針,雙鏈表兩個(gè)指針,但是樹(shù)有多少個(gè)指針是不確定的,因?yàn)闃?shù)沒(méi)有規(guī)定一個(gè)節(jié)點(diǎn)最多有多少個(gè)孩子。那我們?cè)撊绾味x結(jié)構(gòu)呢?

?? 方式一:假設(shè)說(shuō)明了樹(shù)的度為N,才能勉強(qiáng)用

struct TreeNode {
    int data;
    struct TreeNode* sub[N]; // 指針數(shù)組
};

問(wèn)題點(diǎn):

① 可能會(huì)存在不少的空間浪費(fèi)。 

② 萬(wàn)一沒(méi)有限定樹(shù)的度為多少呢?這個(gè)方式就廢了。

?? 方式二:vector

// 假設(shè)我們定義了一個(gè)順序表
// typedef int STLDataType;  //順序表的數(shù)據(jù)類(lèi)型
 
// 順序表中存節(jié)點(diǎn)的指針
typedef struct TreeNode* SLDataType; //SeqList
 
struct TreeNode {
    int data;
    SeqList s;  // s為SLDataType* array;
};

(C++中這里可以用 vector,但是C里沒(méi)有)

即使你沒(méi)有告訴我度是多少,我有多少個(gè)孩子我就存多少個(gè)孩子,所以這里不需要關(guān)心度的問(wèn)題。但是這里 s 的結(jié)構(gòu)相對(duì)復(fù)雜,s 里面有一個(gè)類(lèi)型為SLDataType* 的數(shù)組,這個(gè)數(shù)組已經(jīng)是二級(jí)指針了,SLDataType 展開(kāi)后又是一個(gè) struct TreeNode* 。

?? 方式三:雙親表示法

利用結(jié)構(gòu)數(shù)組存儲(chǔ)(更加復(fù)雜)

struct TreeNode {
    int parenti;
    int data;
};

[ A -1] [ B0 ] [ C0 ] [ D0 ] ...... [ H 3 ]  

   ??  每一個(gè)元素中存的是結(jié)構(gòu)體   struct TreeNode arr[10]

每個(gè)元素內(nèi)只存自己的值和父親的下標(biāo)(A沒(méi)有父親是-1,B的父親下標(biāo)是0…… H的父親是D下標(biāo)為3),可以通過(guò)一個(gè)值找到自己父親。

? 上列的方式各有優(yōu)缺點(diǎn),那么有沒(méi)有最優(yōu)的方法?

? 當(dāng)然有,它就是 —— 《左孩子右兄弟表示法》  有了這個(gè)方法,其他的都是渣渣!

typedef int DataType;
 
struct Node {
    struct Node* _firstChind1;   // 永遠(yuǎn)指向第一個(gè)孩子
    struct Node* _pNextBrother;  // 指向孩子右邊的兄弟
    DataType _data;
};

?? 解讀:無(wú)論你有多少個(gè)孩子,它都只存兩個(gè)指針。一個(gè)指針永遠(yuǎn)指向第一個(gè)孩子,另一個(gè)指針指向孩子右邊的兄弟(親兄弟)。這個(gè)樹(shù)的度無(wú)論為多少,也不需要用順序表存,但是你任何一個(gè)節(jié)點(diǎn)有多少個(gè)孩子都能給你表示出來(lái),通過(guò)第一個(gè)孩子把所有孩子都找出來(lái)。不復(fù)雜也沒(méi)有浪費(fèi),只用兩個(gè)指針就把鏈接關(guān)系都表示出來(lái)了,不得不說(shuō)設(shè)計(jì)這個(gè)的人真是太????了!

 0x03 樹(shù)在實(shí)際中的運(yùn)用

文件系統(tǒng)的目錄樹(shù)結(jié)構(gòu)、網(wǎng)絡(luò)拓?fù)?,最短路徑?wèn)題,搜索引擎、思維導(dǎo)圖等

到此這篇關(guān)于C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)系列之樹(shù)的常見(jiàn)表示方法的文章就介紹到這了,更多相關(guān)C語(yǔ)言 樹(shù)的常見(jiàn)表示方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言中fgets和fscanf區(qū)別詳解

    C語(yǔ)言中fgets和fscanf區(qū)別詳解

    這篇文章主要介紹了C語(yǔ)言中fgets和fscanf區(qū)別詳解的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10
  • c++ 中__declspec 的用法詳解

    c++ 中__declspec 的用法詳解

    這篇文章主要介紹了c++ 中__declspec 的用法詳解,對(duì)初學(xué)者有一定的幫助,有需要的可以了解一下。
    2016-11-11
  • C++學(xué)習(xí)之Lambda表達(dá)式的用法詳解

    C++學(xué)習(xí)之Lambda表達(dá)式的用法詳解

    Lambda?表達(dá)式(lambda?expression)是一個(gè)匿名函數(shù),Lambda表達(dá)式基于數(shù)學(xué)中的λ演算得名。本文就來(lái)為大家詳細(xì)講講C++中Lambda表達(dá)式的使用,需要的可以參考一下
    2022-07-07
  • C++ STL標(biāo)準(zhǔn)庫(kù)std::vector的使用詳解

    C++ STL標(biāo)準(zhǔn)庫(kù)std::vector的使用詳解

    vector 是表示可以改變大小的數(shù)組的序列容器,本文主要介紹了C++ STL標(biāo)準(zhǔn)庫(kù)std::vector的使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C++初階學(xué)習(xí)之模板進(jìn)階

    C++初階學(xué)習(xí)之模板進(jìn)階

    這篇文章主要為大家介紹了C++模板進(jìn)階,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • OpenCV圖像文件批量讀取編程實(shí)例

    OpenCV圖像文件批量讀取編程實(shí)例

    這篇文章主要為大家詳細(xì)介紹了OpenCV圖像文件批量讀取編程實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C語(yǔ)言#define定義宏的使用詳解

    C語(yǔ)言#define定義宏的使用詳解

    #define?機(jī)制包括了一個(gè)規(guī)定,允許把參數(shù)替換到文本中,這種實(shí)現(xiàn)通常稱(chēng)為宏(macro)或定義宏(define?macro)。本文就來(lái)和大家聊聊宏的使用,需要的可以參考一下
    2022-10-10
  • 深入理解C++內(nèi)鏈接與外鏈接的意義

    深入理解C++內(nèi)鏈接與外鏈接的意義

    鏈接描述了名稱(chēng)在整個(gè)程序或一個(gè)翻譯單元中如何引用或不引用同一實(shí)體,下面這篇文章主要給大家介紹了關(guān)于C++內(nèi)鏈接與外鏈接意義的理解,需要的朋友可以參考下
    2021-11-11
  • C語(yǔ)言詳細(xì)圖解浮點(diǎn)型數(shù)據(jù)的存儲(chǔ)實(shí)現(xiàn)

    C語(yǔ)言詳細(xì)圖解浮點(diǎn)型數(shù)據(jù)的存儲(chǔ)實(shí)現(xiàn)

    使用編程語(yǔ)言進(jìn)行編程時(shí),需要用到各種變量來(lái)存儲(chǔ)各種信息。變量保留的是它所存儲(chǔ)的值的內(nèi)存位置。這意味著,當(dāng)您創(chuàng)建一個(gè)變量時(shí),就會(huì)在內(nèi)存中保留一些空間。您可能需要存儲(chǔ)各種數(shù)據(jù)類(lèi)型的信息,操作系統(tǒng)會(huì)根據(jù)變量的數(shù)據(jù)類(lèi)型,來(lái)分配內(nèi)存和決定在保留內(nèi)存中存儲(chǔ)什么
    2022-05-05
  • C++類(lèi)型轉(zhuǎn)換運(yùn)算符詳解

    C++類(lèi)型轉(zhuǎn)換運(yùn)算符詳解

    這篇文章主要介紹了C++類(lèi)型轉(zhuǎn)換運(yùn)算符的相關(guān)資料,希望通過(guò)本文大家能夠掌握這部分內(nèi)容,需要的朋友可以參考下,希望能夠給你帶來(lái)幫助
    2021-10-10

最新評(píng)論