樹、堆算法
一、一課樹中的任意兩個結點有僅有惟一的一條路徑連通。
二、一棵樹若是有n個結點,那麼它必定剛好有n-1條邊。
三、在一棵樹中加一條邊將會構造一個迴路。數組
滿二叉樹:二叉樹全部的葉結點都有一樣的深度。
深度爲:n,結點數:2**n - 1數據結構
若是一棵二叉樹除了最右邊位置上有一個或者幾個葉結點缺乏外,其餘是豐滿的,那麼這樣的二叉樹就徹底二叉樹。嚴格的定義是:若設二叉樹的高度爲h,除h層外,其餘各層(1~h-1)的結點數都達到最大個數,第n層從右向左連續缺若干個結點,則這個二叉樹就是徹底二叉樹。優化
經過上圖咱們發現,若是徹底二叉樹的一個父結點編號爲k,那麼它左兒子的編號就是2*k,右兒子的編號就是2*k+1。若是已知兒子(左兒子或右兒子)的編號是x,那麼它父結點的編號就是x/2,注意這裏只取商的整數部分。
若是一顆徹底二叉樹有N個結點,那麼這個徹底二叉樹的高度爲log2N,簡寫logN,即最多有logN層結點。徹底二叉樹的最典型應用就是一個堆。spa
最大堆:全部父節點都比兒子結點要大;
最小堆:全部父節點都比兒子結點要小;3d
很顯然最小的數就在堆頂,假設存儲這個堆的數組叫作h的話,最小數就是h[1]。接下來,咱們將堆頂的數刪除。將新增長的數23放到堆頂。顯然加了新數後已經不符合最小堆的特性,咱們須要將新增長的數調整到合適的位置。那如何調整呢?blog
向下調整!咱們須要將這個數與它的兩個兒子2和5比較,選擇較小的一個與它交換,交換以後以下。排序
咱們發展此時仍是不符合最小堆的特性,所以還須要繼續向下調整。因而繼續將23與它的兩個兒子12和7比較,選擇較小一個交換,交換以後以下。隊列
至此,仍是不符合最小堆的特性,仍須要繼續向下調整,直到符合最小堆的特性爲止。it
如今咱們發現已經符合最小堆的特性了。綜上所述,當新增長一個數被放置到堆頂時,若是此時不符合最小堆的特性,則須要將這個數向下調整,直到找到合適的位置爲止,使其從新符合最小堆的特性。
時間複雜度:logN
固然目前這個棵樹仍然不符合最小堆的特性,咱們須要繼續調整以3號結點爲根的子樹,即將3號結點向下調整。
同理,繼續調整以2號結點爲根的子樹,最後調整以1號結點爲根的子樹。調整完畢以後,整棵樹就符合最小堆的特性了。
像這樣支持插入元素和尋找最大 (小)值元素的數據結構稱爲優先隊列。若是使用普通隊列來實現這兩個功能,那麼尋找最大元素須要枚舉整個隊列,這樣的時間複雜度比較高。若是是已排序好的數據,那麼插入一個元素則須要移動不少元素,時間複雜度度依舊很高。而堆就是一種優先隊列的實現,能夠很好地解決這兩種操做。
另外Dijkstr算法中每次找離源點最近的一個頂點也能夠用堆來優化,使算法的時間複雜度降到O((M+N)logN)。堆還常常被用來求一個數列中第K大的數,只須要創建一個大小爲K的最小堆,堆頂就是第K大的數。
注:內容來源於《啊哈.算法》