以下給出我在學習中總結的一種比較簡便的構造折半二叉判定樹的思路以及方法:
思路分析:
在計算mid值時,使用的時mid=(low+high)/2 。這裏由於mid爲int類型,自動默認爲向下取整,因此對於一個長度爲n序列進行劃分之後的序列爲 (0,1,2,……,mid-1)mid(mid+1,mid+2,……n-1),此時出現兩種情況:
- 左子序列長==右子序列長 (n=2k+1 k=0,1,2,……)
- 左子序列長==右子序列長-1 (n=2k k=1,2,3,……)
因此可以得知,折半查找的二叉判定樹對於所有結點,左子樹結點個數<=右子樹結點個數。即:
- 若某序列總長n爲奇數,左右子樹結點個數相等;
- 若某序列總長n爲偶數,左字數結點個數=右子樹結點個數-1.
換句話說,對判定樹中所有結點都有:
(左子樹結點數-右子樹結點數==-1)||(左子樹結點數-右子樹結點數==0)
由此給定某個序列,構建折半查找判定樹方法如下三步:
- 按照結點總數先畫出最大的滿二叉樹結構,並計算剩餘幾個結點。
- 將剩餘結點按照上述的規律依次填入最底層即爲二叉判定樹的樹形。
- 將給定序列依次按照中序遍歷順序填入各個結點。
具體如下面的例子:
例:畫出(2,5,7,10,14,15,18,23,35,41,52)的折半查找判定樹。
1.序列總長度爲n=11>2^3-1 即二叉判定樹爲4層,前三層爲滿二叉樹結構,剩餘4個結點。
先畫出前三層結構。
2.
1)第一個結點。a的左右子樹結點個數相等,所以新的結點應加入a的右子樹;再看a的右子樹,c的左右子樹結點個數相等,所以新結點應加入c的右子樹;再看c的右子樹,g的左右子樹結點個數相等,所以新結點應加入g的右子樹;如圖
2)第二個結點。a的左子樹結點數-右子樹結點數=-1,所以新結點應加入a的左子樹(若加入右子樹,對於a來說左右子樹結點之差=-2,不符合規律);再看a的左子樹,b的左右子樹結點個數相等,所以新結點應加入b的右子樹;再看b的右子樹,e的左右子樹結點個數相等,所以新結點應加入e的右子樹。如圖
3)同理分析,第三個結點應加在如圖位置。
4)第四個結點加在如圖位置。
得到最終的樹形如上圖。(字母編號不唯一,但後面中序遍歷結果會不同)
3.該二叉樹的中序遍歷順序爲dkbeiafjcgh,分別對應2,5,7,10,14,15,18,23,35,41,52。因此將序列一一對應填入樹中,即
該樹即爲此序列的二叉判定樹。
做題過程中熟練使用此方法比通過算法模擬來推斷二叉判定樹的速度要快許多倍。
在平時做題過程中,涉及到需要具體畫出二叉判定樹的題目,往往結點個數(序列長度)不超過2^4-1=15個,即一般爲高度不超過4的樹,因此可以在練習時將結點個數8-14的所有樹形畫幾遍,就可以很熟練的掌握這個方法。
二叉判定樹畫出之後便可以對其他具體題目進行分別的計算,如求成功或失敗的查找長度、求比較順序、比較次數等。