1. 程式人生 > >從零開始_學_資料結構(二)——樹的基本概念

從零開始_學_資料結構(二)——樹的基本概念

相比之前的帖子,對其進行了增添和完善。

ps:本顏色的字型是後續新增內容

——————————————————

參考連結:

大話資料結構.pdf

http://www.cnblogs.com/yc_sunniwell/archive/2010/06/27/1766233.html

1.什麼是樹?

是一種資料結構,可以用來表示層次關係,因表示的樣子很像一顆倒立的樹而得名。

在資料結構中的特點,是一對多(連結串列是一對一,圖是多對多)

 

最上面;樹根

中間:樹枝

最下:樹葉

2.樹的定義。

如圖:

 

樹定義(無根樹):

①一個無根樹是一個二元組(V,E);              //V是頂點集(非空集合),E是邊集(V中元素構成的無序二元組的集合)

(注:個人理解,就是有至少1個點,可以有很多個,這些點的集合,就是V,稱為頂點集,我覺得可以理解為結點的集合;

然後這些結點,將會連城一些線段,並且每條線段都沒有方向(這裡的方向,我認為可以理解為從一個點連向另外一個點,至於為什麼說沒有方向,我覺得是因為沒有起點和終點,線段只是將兩個點連起來而已,所以稱為沒有方向),而這些線段的結合,就是E,稱為邊集)

在離散數學中,無根樹指無環連通無向圖。

所謂的 無向圖,就是一個圖中若每條邊都是沒有方向的,則稱為無向圖。

參考連結:http://baike.baidu.com/view/93110.htm

無向圖中的邊,均是頂點的無序對,無序對通常用圓括號表示。

(注:據我理解,所謂的無序對,就是拿出某個圖中的兩個點,例如v1和v2,然後(v1,v2)表示的邊,和(v2,v1)表示的邊是一樣的。而像(v1,v2)這樣表示,就是指的是無序對,正是因為邊沒有方向,所以兩種表示方法表示的線段才是一樣的)

無根樹要求每個頂點之間都是直接或者間接相連,且圖中沒有環(即只有簡單路徑)。

(注:因為不能有環,所以任意兩個點之間,只有一條路徑能走的通,假如有兩條路徑能走得通,就形成了一個環了)

由於樹是圖的子集(圖是什麼?推測指的是資料結構?),這一類圖具有樹的特徵,但不具備數的形式,沒有特定的根結點,故稱為無根樹。

(注:這說明,無根樹和有根樹幾乎是一樣的,除了有根樹有根結點,而根結點又是指定的,即給一個無根樹,然後指定一個結點為根,那麼這個無根樹就成為了有根樹)

樹是nn0)個結點的有限集。n=0時稱為空樹,在任意一棵非空樹中:

1)有且僅有一個特定的稱為根(root的結點;

2)當n1時,其餘結點可分為mm>0)個互不相交的有限集T1T2T3......Tm,其中每個集合本身又是一棵樹,並且稱為根的子樹。

用上圖舉例子的話,就是A為根時,是一棵樹,然後這棵樹從根部分離出以BCD三個結點為根的子樹,其中B子樹有2個結點,C子樹有7個結點,D1個結點。

注:

①當n>0時,即至少有一個結點時,那麼樹必然有一個根結點,且只有一個根結點;

②子樹之間必然是互不相交的(否則就會出現多個上級結點指向同一個下級結點,或者是同級結點之間互相連線)

有根樹:

①樹根:在無根樹中,可取樹中任意一個結點為根r,使樹變為一顆有根樹。

②父子關係:(1)對於任意非根結點v,v到樹根r的路徑上的第一個結點p,定義為v的父結點,而v是p的子結點。

(2)一個結點可以有多個子結點(也可以是0個,例如這個樹中,只有一條線連線著這個結點);

(3)非根結點只能有一個父結點(如果是根出來的第一個結點,那麼這個結點就是自己的父結點麼?

(4)樹根沒有父結點。

資料結構中的樹一般是有根樹。

有根樹:

①有根樹的遞迴定義:

(1)沒有結點是一棵樹(可稱為空結點);

(2)單獨的一個結點是一顆樹;

(3)如果t0、t1、t2、……、tk-1是一顆樹,t是一個結點,則將t0、t1、t2、……、tk-1作為t的子結點後,組成的樹t,也是一棵樹,樹根為t。(注意:一般有根樹使用根結點來標識)

——我猜測,從t0tk-1之間應該也可以將其分別視為一個結點,然後進行連線(以樹的形式,即任意兩個結點之間只有一條路徑),就形成了一個有根樹(樹根為t

樹的深度和高度:

樹的高度和樹的深度似乎不一樣,貌似說法有幾種(比如某些大學教科書):

有的說高度和深度一樣;

有的說高度比深度少一;

有的說根結點從0開始計算;

有的說根結點從1開始計算。

根據我個人理解,如圖那樣,有5層,根直接相連的,其深度則為1,高度為3;最下層的,其深度為4,高度為0。

推測,深度就是指從根開始的距離(即從根開始計算,假如根為第0個結點,那麼連線他和根的線段中,他是第幾個結點,深度就是幾);

而高度就是指,一個結點,和最底層距離有多遠,假如最多是5層,這個結點和根的距離只有1(即位於第4層),那麼他的高度就是4。

3.二叉樹

二叉樹是樹的一種。

二叉樹的特徵是,除了葉以外的結點,都有兩個子。(葉就是在它和根的路徑上,沒有比他更遠的結點了,也可以理解為,只有一個結點和它相連,並且它不是根,那麼他就是葉)

簡單來說,就是在有根樹的基礎上,一個結點,往更深的地方延伸時,最多隻能延伸出來零個,或者兩個結點(只能是0個或者2個,不能是1個。如果是0個就是葉,否則就是結點),那麼他就是二叉樹。

例如:圖中延伸出0個結點(葉)有:E,G,H,I,J,K

而延伸出2個結點的有:A,B,C,D,F

4.樹的遍歷

所謂樹的遍歷,是指對樹中所有結點的資訊的訪問。

其重點有2個:

①對所有結點進行訪問(假如有結點沒有被訪問,肯定算不上遍歷了)

②對每個結點只訪問一次;

說起遍歷,那麼前提是樹必須有順序。

    假如A結點是根結點,B和C是他的子(二叉樹)。那麼如何遍歷呢?

    先訪問A再訪問B最後C?還是A->C->B?又或者是先訪問B或者C?

    這些都是不一樣的。

只有有了順序,才能決定怎麼訪問。同樣以A、B、C三個結點為例,A是根結點,B左C右,或者是B右C左,其並非是同一個樹。

    根據我個人所知推斷,假如有這樣一個樹,他最終是要儲存到硬盤裡的,如果B在A左邊,C在A右邊,其必然是有一定原因和規律的。例如,三個數都是int值,B=10,A=20,C=30。那麼以陣列形式儲存,其為{B,A,C}。比A小的放A左邊,比A大的放A右邊,陣列以增序排列。假如值不變,形式為{C,A,B},那麼陣列就變為以減序排列了。增序和減序,顯然是不一樣的。

因此,樹的左右順序是不能顛倒的。

疑問:我找的資料上說的是二叉樹其左右是不能顛倒的,那麼三叉樹,或者其他樹可以顛倒麼?我推測應該也是不能的吧,至於為什麼,需要查查資料。

二叉樹的遍歷方法主要有三種:

①前序遍歷;(先訪問根結點,再訪問子結點)

②後序遍歷;(先訪問子結點,再訪問根結點)

③中序遍歷(只適用於二叉樹)

 

前序遍歷:

順序:訪問根結點——》訪問左子樹——》訪問右子樹

在訪問子樹,依然按該順序進行訪問。

 

以上圖中的二叉樹為例,前序遍歷的順序是

其邏輯是:

(1)先訪問根;

(2)當前如果是根,且無子結點,則結束;如果是根,有子結點,第二次返回根的時候結束;(在程式設計時如何做到這一點?

(3)檢視有沒有沒有訪問過的子結點(問題,如何判斷是不是訪問過的):

(3.1)如果有,則訪問子結點的左邊部分,重複(2);

(3.2)如果沒有,則判斷當前結點是不是子結點的左結點:

(3.2.1)如果是,則訪問右結點,重複(2);

(3.2.2)如果不是,返回父結點,重複(2)

後序遍歷:

順序:訪問根結點——》訪問右子樹——》訪問左子樹

順序正好和前序遍歷相反。

所以,具體的就省略了。

中序遍歷:

所謂的中序遍歷,就是指,先訪問左子樹,再訪問根,再訪問右子樹。

具體到每一個子樹時,也是如此。

與前序遍歷和後序遍歷不同的是,中序遍歷在訪問子樹的過程中,並不直接訪問路徑上的,而是先要確定該子樹還有沒有子結點,如果沒有了,才訪問它,如果有,則繼續訪問子樹的子樹。

例如:


以圖為例,由於B是A的子,D是B的子,H是D的子,而H沒有子了。因此,先訪問H。

然後訪問H的父(D),訪問D。

然後D的右子是I,因此訪問I。

I沒有子了,返回D;D的子樹訪問完了,因此返回D的父(B),訪問B;

B的右子,因此訪問E;

E沒有子了,因此返回B,而B的子樹也訪問完了,因此返回A,訪問A;

A的右子樹是C,而C有子(F),F有子(J),J無子,因此訪問J;

返回J的父F,訪問F;

F的右子是K,訪問K;

K無子,返回F,F的子樹訪問完了,返回C,C的右子是G,G無子,訪問G。

樹的遍歷結束。其順序是:H-D-I-B-E-A-J-F-K-C-G。

形象的說,就是先訪問左子樹,假如左子樹沒有子,則訪問結點,並返回,訪問父,再訪問父的右子樹。然後重複即可。——左-父-右的順序

樹的結點

包括一個數據元素,和從這個元素,指向其各個子樹的分支(但不包括指向其父樹的分支)。

結點擁有的子樹數,稱為結點的度Degree),度為0的結點,稱為葉結點Leaf)或終端節點;

度不為0的結點,稱為非終端結點分支結點

除根結點外,分支結點也稱為內部結點。

樹的度為樹內各節點的度的最大值

簡單來說,樹的每個結點都有度,看他往下連向幾個結點(只考慮下一層,不考慮更深部分),其度就是幾,沒有就是0

沒有繼續往下連線的(葉),就是葉結點;

不是根也不是葉的,就是內部結點;

每個結點都有度,所有結點中,度最大的結點的度,就是樹的度。

樹的順序:

之前說過,二叉樹的結點的左右子樹是不能交換的,也就是說,有順序的。

假如一個樹,其結點的子樹之間的左右順序,是有次序的,不能互相交換,那麼就說這個樹是有序樹,否則就是無序樹