計算機中樹的優點與重要性
關於樹
樹是含有
|V| 個節點|V|−1 條邊的最小無向連通圖。在計算機中,樹隨處可在,可說是圖論和電腦科學中的重中之重。
理解樹的結構,樹的思想和樹的優異性質對於程式設計大有裨益。
我將由多個方面入手闡述這一優雅的結構。
樹作為圖的優異性質
- 樹的大小是確定的,只需要
Θ(|V|) 的空間。- 樹是連通的,只需要進行一次搜尋就可以完成遍歷。
- 當樹的根確定了,任意兩點間的關係也唯一確定了,也可看做有向圖。
- 樹的連通子圖也是樹。
- 當樹較均勻時,從根到葉的步數
∼Θ(log|V|) - 樹上兩兩節點之間存在唯一的簡單路徑。
樹可說是一類非常特殊的圖,由於其特殊的性質,科學家們創造許多獨屬於樹的演算法,方便處理樹形結構,也通過樹形結構解決了大量演算法問題,資料儲存問題和程式呼叫的問題。
樹在計算機體系中的作用
在計算機體系中,樹的地位是無可替代的。
計算機的核心是計算和儲存,而樹有效地解決了儲存的問題和計算時程式呼叫的問題。
程式呼叫與樹
計算機中的一個關鍵就是如何建立程式之間的呼叫關係。科學家們利用棧的結構很好地處理了這個問題,程式的遞迴和棧的操作實質上都是建立在樹形結構的基礎上的。
實際上棧的
push 和pop 操作與樹訪問子節點和回到父節點的效果是等價的,棧底到棧頂的元素實際上就是根到當前節點的元素。遞迴程式具象化表達之後,我們都稱之為遞迴樹,棧和樹其實都可以表達程式之間呼叫的關係。
程式之間呼叫的關係就是,被呼叫的程式應當在呼叫程式完成之前完成,這其實是建立在程式之間的偏序關係。其對應概念為棧之中先入棧的元素出棧之前後入棧的要先出棧,樹之中要退到父節點必須先退出子節點。實質上棧和樹可以表達程式之間的偏序關係。而選擇棧而非樹的原因就是程式呼叫中很多時候不需要退出一個程式的路徑的資訊,自然無需真的構建一張圖,棧可以更高效地做到樹做到的事情。
雖然計算機中使用了樹作為建立程式呼叫關係的資料結構,但是實質上當人理解程式呼叫的時候更多地會需要利用樹形結構,因為路徑資訊可以輔助理解程式的遞迴呼叫和了解遞迴程式的執行方式。
記憶體管理與樹
說到記憶體就不得不提到與棧並稱的堆了。堆是可以持久化管理和儲存資料的資料結構。
實際上堆是一顆不用儲存邊的完全二叉樹,可以通過節點間的關係展開。
通常我們建的都是小根堆,我們保證了父節點比子節點小。由此我們可以推出任何一條從根開始的鏈都是遞增的。由於樹是連通的,可以構建從根到任意非根節點的鏈,所以根小於所有非根節點。
實質上在堆中,我們將
x<y 的關係直接轉化為了x 是y 的前驅。仍然是使用樹來維護一個偏序關係的集合,但這其中有一個線性的偏序關係化為立體的樹然後簡化迴歸到線性結構的過程。而由於樹的優秀性質,我們在對堆進行增刪操作的時候只需要
O(logn) 的時間。
樹與演算法
樹形結構在演算法設計中也有著廣泛的應用,其關鍵在於許多演算法在設計的過程中採用了分治的思想,使用了遞迴求解的方法或者需要遍歷可行解,這些程式的執行均可用樹形結構表達,輔助人們理解。
以排序演算法為例,經典的快速排序,歸併排序均為遞迴求解,使用了分治的思想,而堆排序使用的資料結構——堆,在前文已經介紹了其與樹的緊密聯絡。
快排的遞迴樹
歸併的遞迴樹可以說由樹形結構及遞迴思維方式直接就帶給了我們
Θ(nlogn) 的排序複雜度。除了排序演算法之外,圖論,博弈,動態規劃的演算法設計中也經常能看到樹和遞迴的身影,大多數分治和結果相互依賴的演算法均可用樹來表達其遞迴路徑和思想。
樹與資料結構
樹最強大的功能是進行儲存查詢,為此電腦科學家們創造了諸如紅黑樹,AVL樹,B+樹,字典樹,堆,並查集等資料結構,它們被廣泛地運用於計算機的各個方面。
樹能用於設計資料結構大概有以下幾個原因:
- 一顆較均勻的樹其高度
∼Θ(log|V|) ,查詢十分高效- 樹的空間複雜度為
Θ(|V|) ,利於儲存- 樹的性質可以一直被維護,能設計出持久化儲存管理資料的結構
- 樹可以遞迴定義,其子樹也滿足定義,便於在增刪的時候調整結構以維護樹的定義
- 樹的擴充套件性強,通過微調可以適應環境的變化。
- 樹能可以展現偏序關係(dfs序)和全序關係(中序)