對於大量的輸入資料,鍊錶的線性訪問時間太慢,不宜使用。我們介紹一種簡單的資料結構,其大部分操作的執行時間平均為o(log n)。涉及到這種資料結構叫做二叉查詢樹,在電腦科學中樹(tree)是非常有用的抽象概念。
樹可以用幾種方式定義。一種定義樹的自然的方式是遞迴的方法。一棵樹是一些結點的集合。這個集合可以是空集;若非空,則一棵樹由稱作根(root)的節點r,以及0個或多個非空的子樹t1,t2,t3,...,tk組成,這些子樹中每一棵的根都被來自根r的一條有向邊(edge)所連線。
每一棵子樹的根叫做根r的兒子(child),而r是每一棵子樹的根(root)的根的父親(parent)。一棵樹是n個節點和n-1條邊的集合,其中的乙個節點叫做根。每條邊都將某個節點連線到它的父親,而除去根節點外每乙個節點都有乙個父親。每乙個節點都可以有任意個兒子,也可能有零個兒子。沒有兒子的結點叫做樹葉(leaf);具有相同父親的結點叫做兄弟(sibling)。用類似方法可以定義祖父(grandparent)和孫子(grandchild)關係。
從節點n1到nk的路徑(path)定義為結點n1,n2,n3,...,nk的乙個序列,使得對於1<=i<=k,節點n(i)是n(i+1)的父親。這條路徑的長(length)為該路徑上的邊的條數,即k-1。對任意節點n(i)的深度為從根到n(j)的惟一路徑的長。因此,根的深度為0。n(i)的高是從n(i)到一片樹葉的最長路徑的長,因此所有樹葉的高為0。一棵樹的高等於它的根的高,一棵樹的深度等於它的最深的樹葉的深度,該深度總是等於這棵樹的高。
實現樹的一種方法可是實在每乙個節點出資料外還要有一些指標,使得該節點的每乙個兒子都有乙個指標指向它。將每個節點的所有兒子都放在樹節點的鍊錶中。
typedef struct treenode *ptrtonode;
struct treenode
;
樹有許多應用。流行的用法之一是包含unix, vax/vms和dos在內的許多常用操縱系統的目錄結構。例如,unix目錄的根是/usr,/usr有三個兒子:mark、alex和bill,它們自己也是目錄。這種分級檔案系統非常流行,因為他能夠使得使用者邏輯地組織資料。在不同目錄下的兩個檔案還可以享有相同的名字,因為它們必然有從根開始的不同的路徑從而具有不同的路徑名。
我們想要列出目錄中所有檔案的名字,我們的輸出格式為:深度為d(i)的檔案的名字將被d(i)次跳格(tab)縮排後列印出來。
演算法如下:(列出分級檔案系統中目錄的例程)
static void listdir(directoryorfile d, int depth)
}void listdirectory(directoryoffile d)
演算法的核心為遞迴過程listdir,為了顯示根時不在進行縮排,該例程需要從目錄名和深度為0開始。這種遍歷的的策略叫做先序遍歷,在先序遍歷中,對節點的處理工作是在它的諸兒子的節點被處理之前(pre)進行的。還有一種遍歷樹的方法是後序遍歷。在後序遍歷中,在乙個節點處的工作實在它的諸兒子節點被計算後(post)進行的。
二叉樹的每個節點都不能有多於兩個的兒子。二叉樹的乙個性質是平均二叉樹的深度要比n小得多,這個平均深度為o(根號n)。而二叉查詢樹,其深度的平均值是o(log n).不幸的是,這個深度可以大到n - 1的。
因為一棵二叉樹最多有兩個兒子,所以我們可以用指標直接指向它們。樹節點的宣告在結構上類似於雙鏈表的宣告。乙個節點可以在呼叫free刪除後被釋放。
二叉樹的節點宣告:
typedef struct treenode *ptrtonode;
typedef struct ptrtonode tree;
struct treenode
;
表示式樹的樹葉是運算元,比如常數或變數,而其他的節點為操作符。由於這裡所有的操作都是二元的,因此這棵樹正好是二叉樹。我們可以通過遞迴產生乙個帶括號的左表示式,然後列印出在根處的運算子,最後再遞迴地產生乙個帶括號的右表示式而得到乙個(對兩個括號整體進行運算的)中綴表示式,這種一般的方法(左,節點,右)稱為中序遍歷。
另一種遍歷策略是遞迴列印出左子樹,右子樹,然後再列印運算子。比如: a b c * + d e * f + g * + ,這就是字尾表示式,這種遍歷叫做後序遍歷。
第三種遍歷策略是先列印出運算子,然後遞迴地列印出左子樹和右子樹,其結果為: + + a * b c * + * d e f g ,是不太常用的字首記法,這種便利策略為先序遍歷。
資料結構 樹
樹的概念 1.家族樹 在現實生活中,有入如下血統關係的家族可用樹形圖表示 張源有三個孩子張明 張亮和張麗 張明有兩個孩子張林和張維 張亮有三個孩子張平 張華和張群 張平有兩個孩子張晶和張磊。以上表示很像一棵倒畫的樹。其中 樹根 是張源,樹的 分支點 是張明 張亮和張平,該家族的其餘成員均是 樹葉 而...
資料結構 樹
1 定義 樹是一種非線性結構,是一種一對多的資料結構。分析樹的結構,我們用遞迴的方法,根結點下面又可以看做是子樹。2 樹的儲存結構 我們一般用孩子兄弟法儲存。也就是把乙個結點的左邊第乙個孩子放在此結點的左邊孩子,把此結點的右兄弟放在此結點的右邊孩子。這樣就產生了二叉樹。二叉樹和樹可以相互對應。3 二...
資料結構 樹
二叉樹性質回顧 滿二叉樹 完全二叉樹等 給定一棵二叉樹,要求分層遍歷該二叉樹,即從上到下按層次訪問該樹,每一層單獨輸出一行,每一層要求訪問的順序為從左到右。我們在遍歷的過程中將該層節點的孩子節點壓入乙個佇列,這樣就可以實現從上到下一層一層地遍歷該二叉樹。層序遍歷 並分層列印 如果不用分層的話只用佇列...