数据结构五——二叉树
文章出處:極客時間《數(shù)據(jù)結(jié)構(gòu)和算法之美》-作者:王爭。該系列文章是本人的學(xué)習(xí)筆記。
1 樹
1.1 概念
概念:樹、根、父節(jié)點、子節(jié)點、葉子節(jié)點。
幾個度:高度、深度、層。與實際生活中的這幾個概念類比。
高度:從下往上數(shù)(從葉子往根),從0開始。
深度:從上往下看(從根往葉子),從0開始。
層數(shù):深度+1
2 二叉樹
2.1 定義
定義:每個節(jié)點最多有兩個子節(jié)點。
滿二叉樹:除了葉子節(jié)點沒有子節(jié)點,其余每個節(jié)點都有2個子節(jié)點。
完全二叉樹:1 葉子節(jié)點在最下面兩層;2 最后一層的葉子節(jié)點都靠左排列;3 除了最后一層,其他層的節(jié)點達(dá)到最大個數(shù)。
二叉樹的存儲:有兩種方式。一種是鏈?zhǔn)酱鎯?一個節(jié)點存儲數(shù)據(jù),兩個指針分別指向左右子節(jié)點。一種是順序存儲(數(shù)組存儲)。根節(jié)點在下標(biāo)為1的位置。左節(jié)點存儲下標(biāo)為2i=2,右節(jié)點存儲下標(biāo)為2i+1=3。依次類推。下標(biāo)為i的節(jié)點,左子節(jié)點存儲在下標(biāo)為2i的位置,右子節(jié)點存儲在2i+1的位置。
如果一棵樹是完全二叉樹,使用數(shù)組存儲的話,只有下標(biāo)為0的位置是空的,其余完全利用。而且不需要額外的指針,更節(jié)約空間。這也是完全二叉樹單獨提出來的原因。
2.2 遍歷
二叉樹的遍歷有前序遍歷、中序遍歷、后續(xù)遍歷,和層次遍歷。前中后序遍歷是指訪問節(jié)點與其子節(jié)點的相對順序。
前序遍歷:訪問節(jié)點,訪問左子節(jié)點,訪問右子節(jié)點
中序遍歷:訪問左子節(jié)點,訪問節(jié)點,訪問右子節(jié)點
后續(xù)遍歷:訪問左子節(jié)點,訪問右子節(jié)點,訪問節(jié)點
前中后序遍歷是一個遞歸過程。遞歸的重點是不是能寫出遞歸公式。寫遞歸公式的重點是能不能將要解決的問題A,分解為子問題B、C、D,假設(shè)B、C、D已經(jīng)解決,如何利用B、C、D的結(jié)果來解決問題A。
2.3思考題
給定一組數(shù)據(jù)1,3,5,6,9,10。可以構(gòu)造出多少種不同的二叉樹。
答案:卡特蘭數(shù)。
3 二叉查找樹
定義:二叉查找樹中任意一個節(jié)點的左子樹中的每一個節(jié)點都要求小于當(dāng)前節(jié)點,右子樹的任意一個節(jié)點都要求大于當(dāng)前節(jié)點。
3.1 二叉查找樹的查找
當(dāng)要查找一個數(shù)的時候,從根節(jié)點開始。如果要查找的值等于根節(jié)點的值,則返回。如果要查找的值大于根節(jié)點的值,則在右子樹遞歸查找。否則,要從左子樹遞歸查找。
3.2 二叉查找樹的插入
插入操作與查找操作類似。從根節(jié)點開始。如果要插入的數(shù)據(jù)比節(jié)點數(shù)據(jù)大,并且節(jié)點的右子樹是空的,則直接插入右子節(jié)點;如果右子樹不為空,遞歸查找右子樹,尋找插入位置。
如果要插入的數(shù)據(jù)比節(jié)點數(shù)據(jù)小,并且節(jié)點的左子樹是空的,則直接插入左子節(jié)點;如果左子樹不為空,則遞歸查找左子樹,尋找插入位置。
3.3 二叉查找樹的刪除
二叉樹的刪除操作比較復(fù)雜,需要分情況討論。
規(guī)則1:要刪除的節(jié)點是一個葉子節(jié)點,例如55。將其父節(jié)點指向該節(jié)點的引用置為空即可。
規(guī)則2:要刪除的節(jié)點有一個子節(jié)點,例如13。將13父節(jié)點指向該節(jié)點的引用指向13的葉子節(jié)點。
規(guī)則3:要刪除的節(jié)點有兩個子節(jié)點,例如18。在18的右子樹查找最小值19,將18節(jié)點的value值改為最小值19,刪除節(jié)點19,應(yīng)用規(guī)則1或者規(guī)則2刪除節(jié)點19。
二叉樹的刪除還有一種操作方法是將要刪除的數(shù)據(jù)標(biāo)記為刪除狀態(tài),并且真正刪除。這樣做會浪費部分空間,但整體時間復(fù)雜度不會受影響,且實現(xiàn)簡單。
3.4其他操作
查找最大值
查找最小值
中序遍歷得到一個順序數(shù)組,時間復(fù)雜度O(n),非常高效,所以二叉查找樹又被稱為二叉排序樹。
3.5 支持重復(fù)元素
如果要插入的元素有重復(fù)的,該怎么處理?
一種處理方法參考散列表的鏈?zhǔn)酱鎯Α涞拿總€節(jié)點存儲數(shù)值的是一個鏈表,遇到值相同的元素就依次添加到鏈表中。
一種處理方法是,大于等于當(dāng)前節(jié)點的元素都插入到右子樹。當(dāng)要查找的時候,遇到相等的元素不停下來,而是繼續(xù)查找,直到找到所有要查找的值值相同的元素。刪除的時候也是同樣。要刪除每一個等于要刪除值的節(jié)點。
3.6二叉查找樹的時間復(fù)雜度分析
二叉查找樹因為形態(tài)多樣,查找時間復(fù)雜度也不相同。例如圖中第一棵樹已經(jīng)退化為鏈表,時間復(fù)雜度O(n)。
第三棵樹是一棵完全二叉樹。無論查找、插入
刪除,時間復(fù)雜度與它的高度成正比。一棵 包含n個節(jié)點的完全二叉樹,高度是多少?
完全二叉樹每一層節(jié)點數(shù)量是:1、2、4…2k?22^{k-2}2k?2,假設(shè)有k層。最后一層節(jié)點數(shù)量在1到2k?12^{k-1}2k?1之間。假設(shè)最后一層節(jié)點數(shù)量是2k?12^{k-1}2k?1。那么1+2+4+....+2k?1=n1+2+4+....+2^{k-1}=n1+2+4+....+2k?1=n,則k=log2(n+1)k=log_2(n+1)k=log2?(n+1)。假設(shè)最后一層節(jié)點數(shù)量是1,那么1+2+4+....+2k?2+1=n1+2+4+....+2^{k-2}+1=n1+2+4+....+2k?2+1=n,k=log2n+1k=log_2n+1k=log2?n+1。k值的區(qū)間是[log2(n+1),log2n+1][log_2(n+1),log_2n+1][log2?(n+1),log2?n+1]。完全二叉樹的層數(shù)小于等于log2n+1log_2n+1log2?n+1,則完全二叉樹的高度小于等于log2nlog_2nlog2?n。
所以在理想情況下完全二叉樹的時間復(fù)雜度是O(logn)。
4 平衡二叉查找樹-紅黑樹
紅黑樹目前我只了解概念,關(guān)于從二三樹到紅黑樹之后再學(xué)習(xí)。
總結(jié)
以上是生活随笔為你收集整理的数据结构五——二叉树的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Depth-first Search深度
- 下一篇: 评价——模糊综合评价