鏈表一般能夠提供比數組更大的靈活性,可是因爲鏈表是線性結構,因此很難使用它們來組織對象的分層結構。雖然棧和隊列反映了某些層次,但它們是一維的。爲了不這種限制,咱們來探究一種新的數據結構,稱爲樹,樹由節點和弧組成。
與天然界的樹不一樣,數據結構中的樹是倒過來的:根在頂部,葉子(末端節點)在底部。根是一個沒有父節點只有子節點的節點,而葉節點沒有子節點或者子節點是空結構。一顆樹中非葉子節點咱們稱之爲非終端節點,包括根節點。
每一個節點均可以從根節點經一個惟一的弧序列到達,此弧序列被稱之爲路徑,路徑中弧的數量稱之爲路徑的長度。節點的層次是從根節點到該節點的路徑的長度加1,也就是該路徑上節點的數量。樹的高度(深度)是樹中節點的最大層次。空結構是空樹,因此空樹高度爲0。只有一個根節點的樹的高度是1,並且該樹比較特殊,它是「節點既是根也是葉子」的惟一狀況。在一棵樹中,若是某個節點擁有n個子節點,那麼咱們稱該節點的度爲n。樹在極端狀況下能夠退化爲鏈表,這種樹的高度爲惟一葉節點的層次。
什麼是二叉樹呢?上面說的都是樹的概念,節點下面能夠有多個子節點,而二叉樹對此作了限制。二叉樹是節點能夠包含最多兩個子節點的樹,每個子節點都區分左子節點或右子節點。例如圖1-1中13和23節點分別是根節點的左右子節點。咱們進一步對二叉樹進行劃分:
在一棵二叉樹中,若是每一個非終端節點都有兩個子節點,而且全部葉子節點位於同一層次,那麼稱之爲完美二叉樹。
其中非終端節點包括15/13/23,它們都有兩個子節點,而且全部葉子節點都位於第3層。能夠看到,完美二叉樹左右子樹是完美對稱的。對於完美二叉樹,有如下特性:
二、若是完美二叉樹高度爲n,那麼總的節點數爲2^n - 1
三、若是完美二叉樹中葉子節點爲m,非終端節點爲k,那麼m=k+1
四、若是完美二叉樹中某節點下標爲n,那麼它的左節點下標爲2n+1,右節點下標爲2n+2
一、性質1能夠用數學概括法來證實,假設完美二叉樹中第i層節點數爲2^(i-1),咱們只要推導出第i+1層節點數爲2^i便可。從定義出發,已知第i層的節點都有兩個左右子節點,那麼第i+1層的節點數爲(2^(i-1))*2,也就是2^i,證實完畢
二、性質2由性質1衍生出來,對於高度爲n的完美二叉樹,節點總數爲2^0+2^1+......+2^(n-1),也就是2^n - 1,證實完畢
三、性質3也是由數學概括法證實的,假設高度爲n的完美二叉樹中非終端節點數爲k,葉子節點爲m,而且m=k+1,只要推導出高度爲n+1的完美二叉樹也符合這種狀況便可。假設該樹非終端節點數爲k1,葉子節點數爲m1,能夠計算出k1=k+m,m1=2*m,那麼m1-k1=2*m-(k+m)=m-k=1,即m1=k1+1,證實完畢
四、性質4的證實比較麻煩,假設完美二叉樹第n層存在一個節點下標爲i,那麼第n層剩餘節點個數(包括i節點)爲(2^n-1)-i,即2^n-i-1,咱們記爲k,假設i節點左節點下標爲j,那麼在第n+1層中j節點以前(不包括j節點)節點數爲2^(n+1-1)-2*k=2^n-2*k,咱們記爲m,那麼j-i=m+k=2^n-2*k+k=2^n-k=2^n-(2^n-i-1)=i+1,即j-i=i+1,那麼j=2i+1,證實完畢
對於高度爲K的,有n個結點的二叉樹,當且僅當其每個結點都與高度爲K的完美二叉樹中編號從0至n-1的結點一一對應時稱之爲徹底二叉樹.
在一棵二叉樹中,只存在度爲0或者2的節點,稱該樹爲完滿二叉樹
咱們知道,在二叉樹中只存在度爲0或1或2的節點,記爲n0,n1,n2,那麼二叉樹中節點總數n能夠記爲n=n0+n1+n2。在全部二叉樹中存在一個重要的性質:n0=n2+1。該性質能夠用數學概括法證實,假設在一棵二叉樹p中,度爲2的節點個數爲n2,那麼n0=n2+1,咱們只要證實在度爲2的節點個數爲n2+1的二叉樹q中,該性質不變便可。想象在二叉樹p中,咱們爲某個葉子節點添加左右節點,那麼該二叉樹變爲q,而且度爲2的節點個數增長了1,而葉子節點也增長了1,n0依然比n2大1。想象在二叉樹p中,爲某個度爲1的節點添加一個子節點,那麼該二叉樹變爲q,而且度爲2的節點個數增長了1,而葉子節點也增長了1,n0依然比n2大1。證實完畢
到目前爲止,咱們已經瞭解完美二叉樹、徹底二叉樹、完滿二叉樹,對於完美二叉樹有4個性質,而徹底二叉樹、完滿二叉樹有1個。也許有同窗會以爲二叉樹還有其餘性質,事實上,其餘性質徹底能夠用以上性質直接或間接推導出來,性質記得越少越不容易忘記。
二叉樹不是停留在學術上的數據結構,咱們是要在程序中實現二叉樹,而且運用它的性質來知足軟件開發需求。第一步,咱們首先要遍歷二叉樹,可以遍歷才能對節點進行操做。遍歷二叉樹的方法在下一篇進行探討。