什麼是樹呢?就是乙個節點上會有很多分叉的資料結構。一般的,對於一棵樹,我們需要的結構體為乙個資料塊和幾個指標塊,這就相當於很多個鍊錶交織在了一起,實際上,鍊錶也可以算是一種特殊的樹,而我要講的,也是一種特殊的樹——二叉樹。
對於樹的各個節點,都有兩個屬性,稱為度(degree),他的意思就是這個節點所擁有的子節點的數量。還有乙個屬性,稱為深度(depth),指節點到根的距離。
什麼是二叉樹呢?顧名思義,就是度為二的樹,它長這樣:
如圖所示,在鍊錶中我們需要頭(head),而在樹中我們就需要根(root),a就是這棵二叉樹的根,根據二叉樹的定義,每個節點指向兩個節點,於是b,c被稱為a的孩子(child),我們稱為子節點,a就是他們的父母(parent),可以稱為父節點。因為defg後面不再有其他節點,所以我們稱他們為葉節點(leaf)。
一、斜樹:就是斜著長的樹,比如上圖中只留下abd或者acg的話就是斜樹了。
二、滿二叉樹:如果所有的節點都存在左子樹和又子樹,並且所有的葉的深度都相同,那麼這個樹被稱為滿二叉樹。
三、完全二叉樹:我們對二叉樹進行編號,比如上圖,編為a(1)b(2)c(3)d(4)e(5)f(6)g(7),可以發現,這棵樹一共有7個節點(記為n),但是我們如果刪除g,那麼是6個節點,對於新的這棵樹進行遍歷,和當它滿的時候各點的編號一樣,則它是完全二叉樹。但是如果拿掉的是f,那麼就不是完全二叉樹。滿二叉樹一定是完全二叉樹,完全二叉樹不一定是滿二叉樹。
為什麼說二叉樹特殊呢?因為它有如下的性質:
一、在二叉樹的第i層至多有2i-1個節點。
二、深度為k的二叉樹最多有2k-1個節點。(注意與第一點的區別,乙個是指數為i-1,乙個指數為k但整體-1)
三、具有n個節點的完全二叉樹的深度為[(log2n)]+1.表示取整.
四、對於任意乙個編號為n的節點,如果它有子節點,它的左子節點編號為2n,右節點的編號為2n+1。(這條性質很重要,決定了二叉樹可以用陣列來表示)。
二叉樹主要有三種遍歷方法。
1、先序遍歷:優先遍歷根,然後優先遍歷左節點。圖中的二叉樹先序遍歷後的結果為abdecfg
2、後序遍歷:優先訪問最底層的左節點,圖中的二叉樹後序遍歷後的結果為debfgca
3、中序遍歷:先訪問最下層的葉,並且由左子樹到父節點到右子樹的順序遍歷,圖中二叉樹中序遍歷後的結果為dbefcga
對於圖中的樹,它的編號是這樣的:a(1)b(2)c(3)d(4)e(5)f(6)g(7),利用性質四,就可以很輕鬆的建立一棵順序二叉樹。
我們可以把陣列中的第乙個位置捨棄,因為不方便。我們來看一下如何進行先序輸入吧:
void get_tree(char *tree,int sub)
輸入#號表示該節點為空,不然的話,永遠都輸入不完啦!
那麼先序輸出也就簡單了:
void print_tree(char *tree,int sub)
**很簡潔方便,而且想要某個點的深度只要取該點下標,利用性質三就行了。由於math.h庫裡面沒有log以2為底的函式,所以需要用到換底公式來操作,我就不再多說了。
總體的**如下:
//二叉樹的先序輸入與輸出
#include void get_tree(char*,int);
void print_tree(char*,int);
int main()
void get_tree(char *tree,int sub)
void print_tree(char *tree,int sub)
108將有序陣列轉化為二查搜尋樹
definition for a binary tree node.class treenode def init self,x self.val x self.left none self.right none from typing import list class solution def ...
L3 010 是否完全二叉搜尋樹 陣列模擬樹
時間限制 400 ms 記憶體限制 65536 kb 長度限制 8000 b 判題程式 standard 作者 陳越將一系列給定數字順序插入乙個初始為空的二叉搜尋樹 定義為左子樹鍵值大,右子樹鍵值小 你需要判斷最後的樹是否一棵完全二叉樹,並且給出其層序遍歷的結果。輸入格式 輸入第一行給出乙個不超過2...
線段樹 樹狀陣列 並查集
利用線段樹十分方便的處理區間,線段樹是一棵完美的二叉樹,樹上的每乙個節點都維護乙個區間,根維護的是整個區間,線段樹通常用來計算區間內資料的和或者是修改某處的值。對區間的操作可以再o logn 的時間內完成。下面我們通過 實現線段樹的構建,修改,區間求和。include include 線段樹 def...