二叉搜索樹前驅(qū)節(jié)點(diǎn)的位置及證明

一墩蔓、前言

本文詣在幫助像博主這樣沒有基礎(chǔ)的同學(xué)更好地理解二叉搜索樹中前驅(qū)節(jié)點(diǎn)的求法攘烛,以及為什么這么求就可以舶赔,高手童鞋就忽略吧...這其中可能有我個人理解不準(zhǔn)確的地方湃交,還請幫忙指正熟空。本文所總結(jié)的證明方法都是我自己歸納的所以不一定正確,給需要的同學(xué)作參考搞莺。
接下來就是正文內(nèi)容了


二息罗、前驅(qū)節(jié)點(diǎn)的定義

1. 定義:某個節(jié)點(diǎn)的前驅(qū)節(jié)點(diǎn)指所有值小于該節(jié)點(diǎn)的節(jié)點(diǎn)中值最大的節(jié)點(diǎn)
舉例來說:途中的樹中,9的前驅(qū)是8,8的前驅(qū)是7,7的前驅(qū)是6,2的前驅(qū)是1,1沒有前驅(qū)腮敌。阱当。俏扩。

盜一張圖糜工,哈哈

2. 如何求某個節(jié)點(diǎn)的前驅(qū)呢?

  1. 若一個節(jié)點(diǎn)有左子樹录淡,那么該節(jié)點(diǎn)的前驅(qū)節(jié)點(diǎn)是其左子樹中值最大的節(jié)點(diǎn)
  2. 若一個節(jié)點(diǎn)沒有左子樹捌木,且該節(jié)點(diǎn)是其父節(jié)點(diǎn)的右邊孩子,那么該節(jié)點(diǎn)的前驅(qū)結(jié)點(diǎn)即為其父節(jié)點(diǎn)嫉戚。
  3. 若一個節(jié)點(diǎn)沒有左子樹刨裆,且該節(jié)點(diǎn)是其父節(jié)點(diǎn)的左邊孩子澈圈,那么需要沿著其父親節(jié)點(diǎn)一直向樹的頂端尋找,直到找到一個節(jié)點(diǎn)P帆啃,P節(jié)點(diǎn)是其父節(jié)點(diǎn)Q的右邊孩子(可參考例子2的前驅(qū)結(jié)點(diǎn)是1)瞬女,那么Q就是該節(jié)點(diǎn)的前驅(qū)節(jié)點(diǎn)

3. java實(shí)現(xiàn)

/* 
 * 找結(jié)點(diǎn)(x)的前驅(qū)結(jié)點(diǎn)。即努潘,查找"二叉樹中數(shù)據(jù)值小于該結(jié)點(diǎn)"的"最大結(jié)點(diǎn)"诽偷。
 */
public BSTNode<T> predecessor(BSTNode<T> x) {
    // 如果x存在左孩子,則"x的前驅(qū)結(jié)點(diǎn)"為 "以其左孩子為根的子樹的最大結(jié)點(diǎn)"疯坤。
    if (x.left != null)
        return maximum(x.left);
    // 如果x沒有左孩子报慕。則x有以下兩種可能:
    // (01) x是"一個右孩子",則"x的前驅(qū)結(jié)點(diǎn)"為 "它的父結(jié)點(diǎn)"压怠。
    // (02) x是"一個左孩子"眠冈,則查找"x的最低的父結(jié)點(diǎn),并且該父結(jié)點(diǎn)要具有右孩子"菌瘫,找到的這個"最低的父結(jié)點(diǎn)"就是"x的前驅(qū)結(jié)點(diǎn)"蜗顽。
    BSTNode<T> y = x.parent;
    while ((y!=null) && (x==y.left)) {//滿足條件,不斷往上追溯雨让,直到找到右祖先結(jié)點(diǎn)
        x = y;
        y = y.parent;
    }
    return y;
}

4. 用到的結(jié)論
接下來我們就要證明以上三個結(jié)論的正確性诫舅,在證明這三個結(jié)論正確的過程中需要用到另外三個結(jié)論:
結(jié)論一:在同一棵樹中,若存在關(guān)系a<b<c那么任意a和c的共同路徑都是b的路徑宫患。
結(jié)論二:在同一棵樹中刊懈,若a<b<c 那么任意a和c的共同祖先都是b的祖先(假設(shè)共同路徑不為空,且b與任意a娃闲、c共同祖先都不相等)虚汛。
結(jié)論三:假設(shè)y是x的前驅(qū)節(jié)點(diǎn),要么x是y的祖先皇帮,要么y是x的祖先
這三個結(jié)論是我針對二叉搜索樹的性質(zhì)總結(jié)出來的卷哩,并不標(biāo)準(zhǔn),后面我會給出我的證明方法属拾,現(xiàn)在我們還是先拿來用将谊。

三、前驅(qū)節(jié)點(diǎn)求法的論證

接下來我們就要用這三個結(jié)論來證明三種情況下節(jié)點(diǎn)的前驅(qū)的求法了:

  1. 如果節(jié)點(diǎn)的左子樹不為空那么節(jié)點(diǎn)一定是左子樹的最大節(jié)點(diǎn):
    證明:證明這一點(diǎn)我們只需要證明在節(jié)點(diǎn)x存在左子樹的情況下節(jié)點(diǎn)x的前驅(qū)一定在x的左子樹中即可渐白。
    首先我們假設(shè)節(jié)點(diǎn)x尊浓,左子樹最大節(jié)點(diǎn)為y,假設(shè)在樹的某一處存在一個節(jié)點(diǎn)z纯衍,滿足y<z<x(z必然不在x的左子樹中)栋齿。我們只需要證明z不存在即可。
    根據(jù)結(jié)論一可以知道從根節(jié)點(diǎn)到節(jié)點(diǎn)x都是x和y的共同路徑,所以x也是z的路徑上的祖先瓦堵,同時z<x所以z位于 x的左子樹中基协,這和y是x左子樹中最大節(jié)點(diǎn)矛盾,故樹中不存在一個值z滿足y<z<x菇用。所以如果節(jié)點(diǎn)的左子樹不為空那么節(jié)點(diǎn)一定是左子樹的最大節(jié)點(diǎn)成立澜驮。
  1. 若一個節(jié)點(diǎn)沒有左子樹,且該節(jié)點(diǎn)是其父節(jié)點(diǎn)的右邊孩子惋鸥,那么該節(jié)點(diǎn)的前驅(qū)結(jié)點(diǎn)即為其父節(jié)點(diǎn):

證明:同樣我們假設(shè)節(jié)點(diǎn)x的父節(jié)點(diǎn)為y泉唁,x為y的右孩子所以y<x,假設(shè)在樹中存在一個值z滿足,y<z<x揩慕,那么由結(jié)論結(jié)論一可知從根節(jié)點(diǎn)到節(jié)點(diǎn)y都是x和y的共同路徑亭畜,那么y亦是節(jié)點(diǎn)z的路徑上的祖先之一,且z>y迎卤,所以z位于y的右子樹上此時y的右孩子是x拴鸵,所以z必然位于x的左子樹上,這與x沒有左子樹矛盾蜗搔,所以不存在z使y<z<x劲藐,y即是比節(jié)點(diǎn)x小的最大節(jié)點(diǎn)。所以若一個節(jié)點(diǎn)沒有左子樹樟凄,且該節(jié)點(diǎn)是其父節(jié)點(diǎn)的右邊孩子聘芜,那么該節(jié)點(diǎn)的前驅(qū)結(jié)點(diǎn)即為其父節(jié)點(diǎn)。

  1. 若一個節(jié)點(diǎn)沒有左子樹缝龄, 且該節(jié)點(diǎn)是其父節(jié)點(diǎn)的左邊孩子汰现,那么需要沿著其父親節(jié)點(diǎn)一直向樹的頂端尋找,直到找到一個節(jié)點(diǎn)P叔壤,P節(jié)點(diǎn)是其父節(jié)點(diǎn)Q的右邊孩子(可參考例子2的前驅(qū)結(jié)點(diǎn)是1)瞎饲,那么Q就是該節(jié)點(diǎn)的前驅(qū)節(jié)點(diǎn)(也可能不存在)。
    證明: 該結(jié)論等價于:當(dāng)節(jié)點(diǎn)x的前驅(qū)節(jié)點(diǎn)存在時炼绘,x的前驅(qū)是離x最近的x的祖先中右節(jié)點(diǎn)為x祖先的節(jié)點(diǎn)嗅战。接下來我們證明x前驅(qū)存在時的情況。
    結(jié)論三可知俺亮,假設(shè)z是x的前驅(qū)驮捍,那么要么z是x的祖先,要么x是z的祖先脚曾,因?yàn)閦<x且x沒有左子樹东且,所以x的子樹中不存在比x小的值般妙,可見此時z是x的祖先,且由于x大于z所以x位于z的右子樹中
    假設(shè)y是離x最近的x祖先中右節(jié)點(diǎn)為x的祖先的節(jié)點(diǎn)膛檀,
    (1) 假設(shè)z是x的前驅(qū)驾孔,且z在y的上層丘薛,那么存在關(guān)系z<x,y<x蚓聘。由于z是x的前驅(qū)故z<y<x關(guān)系不成立缅糟,所以有y<z<x成立魔吐,由結(jié)論一可知y和x的任意公共路徑均是z的路徑堵漱,然而z位于y的上層综慎,所以該結(jié)論不成立。
    (2) 假設(shè)z是x的前驅(qū)勤庐,且z在y的下層和x的上層之間示惊,且由于z是x的前驅(qū)故z<y<x關(guān)系不成立,所以y<z<x愉镰,所以z位于y的右子樹內(nèi)米罚,x位于y的右子樹內(nèi),這與y是離x最近的右節(jié)點(diǎn)為x祖先的節(jié)點(diǎn)假設(shè)相悖丈探,故結(jié)論不成立录择。
    綜上,x的前驅(qū)節(jié)點(diǎn)只能是y碗降。

四隘竭、證明結(jié)論二:在同一棵樹中,若a<b<c 那么任意a和c的共同祖先都是b的祖先(假設(shè)共同路徑不為空讼渊,且b與任意a动看、c共同祖先不相等)。

證明:
現(xiàn)假設(shè)一顆存在a<b<c的樹爪幻,假設(shè)a和c的祖先分別為[ac(0),ac(1),ac(2),...,ac(n),ap(n+1),ap(n+2),...],[ac(0),ac(1),ac(2),...,ac(n),cp(n+1),cp(n+2),...]
此時a和c共同祖先集合為[ac(0),ac(1),ac(2),...,ac(n)]
現(xiàn)在我們假設(shè)我們要將與b相等的d插入樹中菱皆,那么,d必然會插到b的位置挨稿,即b與d等價搔预。
所以我們只要證明d插入后的路徑經(jīng)過a、c的共同祖先即可叶组。

  1. 當(dāng)共同祖先數(shù)量等于1時拯田,ac(0)為根節(jié)點(diǎn),所以往ac(0)中插入d時ac(0)一定是d的祖先甩十。
  1. 我共同祖先數(shù)量大于1時:
    我們采用數(shù)學(xué)歸納法來證明共同祖先數(shù)量大于1時d插入一定會經(jīng)過a船庇、c的共同祖先
    定義插入位置p,
    (1) p = 0時侣监,插入的節(jié)點(diǎn)為ac0(根節(jié)點(diǎn))鸭轮,插入后ac0成為d的祖先,且由于(ac1 - ac0)* (d - ac0) > 0橄霉,所以d會繼續(xù)插入下個節(jié)點(diǎn)ac1窃爷,
    (2) p > 0時,我們假設(shè)當(dāng)前插入的節(jié)點(diǎn)位置為n-2時,ac(n-2)
    成為d的祖先且d要插入下個節(jié)點(diǎn)為ac(n-1)按厘,成立医吊。我們只需要證明d插入下個節(jié)點(diǎn)ac(n-1)時ac(n-1)將成為d的祖先且d將繼續(xù)插入ac(n)即可。
    (3) 當(dāng)d插入ac(n-1)時逮京,由于(ac(n)-ac(n-1)) * (d - ac(n - 1)) > 0所以當(dāng)d插入到ac(n-1)時ac(n-1)將成為d的祖先卿堂,并且d將繼續(xù)插入ac(n).
    由數(shù)學(xué)歸納法可知,任意a懒棉、c共同祖先都是d的祖先草描,即b的祖先。

綜合情況1和2可知策严,在同一棵樹中穗慕,若a<b<c 那么任意a和c的共同祖先都是b的祖先(假設(shè)共同路徑不為空,且b與任意a妻导、c共同祖先不相等)

五逛绵、證明結(jié)論一:在同一棵樹中,若存在關(guān)系a<b<c那么任意a和c的共同路徑都是b的路徑栗竖。

證明:

  1. 結(jié)論二可知當(dāng)節(jié)點(diǎn)b等于任何a和c的公共祖先時暑脆,a和c的共同祖先也是b的共同祖先,即a和c的共同路徑也是b的路徑狐肢。
  2. 當(dāng)b等于某一個是a和c的共同祖先時添吗,可以證明,b只能是最其下層的公共祖先份名。
    我們可以用反證法來證明:假設(shè)b可以是a碟联、c的非最下層公共祖先,那么由于a<b<c可知a和c分別位于b的左右子樹上僵腺,也就不會再有任何共同的下層(低于b)公共祖先了鲤孵,所以假設(shè)不成立,因此b只可能是a和c的最下層公共祖先辰如。當(dāng)b是a普监、c的最下層公共祖先時任意a、c的公共路徑都是b的路徑顯然是成立的琉兜。

綜合1,2可知結(jié)論“在同一棵樹中凯正,若存在關(guān)系a<b<c那么任意a和c的共同路徑都是b的路徑⊥泱”成立

六廊散、證明結(jié)論三:假設(shè)y是x的前驅(qū)節(jié)點(diǎn),要么x是y的祖先梧疲,要么y是x的祖先

證明:

反證法:假設(shè)x允睹,y均不是對方的祖先运准,由于x,y在同一棵樹上缭受,那么必然存在一個節(jié)點(diǎn)z使x和y分別位于y和x的左右子樹上胁澳,這樣也就存在關(guān)系y<z<x,那么y就不再是x的前驅(qū)節(jié)點(diǎn)贯涎,矛盾听哭。所以當(dāng)y是x的前驅(qū)節(jié)點(diǎn)時要么x是y的祖先要么y是x的祖先慢洋。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末塘雳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子普筹,更是在濱河造成了極大的恐慌败明,老刑警劉巖,帶你破解...
    沈念sama閱讀 223,002評論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件太防,死亡現(xiàn)場離奇詭異妻顶,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蜒车,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評論 3 400
  • 文/潘曉璐 我一進(jìn)店門讳嘱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人酿愧,你說我怎么就攤上這事沥潭。” “怎么了嬉挡?”我有些...
    開封第一講書人閱讀 169,787評論 0 365
  • 文/不壞的土叔 我叫張陵钝鸽,是天一觀的道長。 經(jīng)常有香客問我庞钢,道長拔恰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,237評論 1 300
  • 正文 為了忘掉前任基括,我火速辦了婚禮颜懊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘风皿。我一直安慰自己河爹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,237評論 6 398
  • 文/花漫 我一把揭開白布揪阶。 她就那樣靜靜地躺著昌抠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鲁僚。 梳的紋絲不亂的頭發(fā)上炊苫,一...
    開封第一講書人閱讀 52,821評論 1 314
  • 那天裁厅,我揣著相機(jī)與錄音,去河邊找鬼侨艾。 笑死执虹,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的唠梨。 我是一名探鬼主播袋励,決...
    沈念sama閱讀 41,236評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼当叭!你這毒婦竟也來了茬故?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,196評論 0 277
  • 序言:老撾萬榮一對情侶失蹤蚁鳖,失蹤者是張志新(化名)和其女友劉穎磺芭,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體醉箕,經(jīng)...
    沈念sama閱讀 46,716評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡钾腺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,794評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了讥裤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片放棒。...
    茶點(diǎn)故事閱讀 40,928評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖己英,靈堂內(nèi)的尸體忽然破棺而出间螟,到底是詐尸還是另有隱情,我是刑警寧澤剧辐,帶...
    沈念sama閱讀 36,583評論 5 351
  • 正文 年R本政府宣布寒亥,位于F島的核電站,受9級特大地震影響荧关,放射性物質(zhì)發(fā)生泄漏溉奕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,264評論 3 336
  • 文/蒙蒙 一忍啤、第九天 我趴在偏房一處隱蔽的房頂上張望加勤。 院中可真熱鬧,春花似錦同波、人聲如沸鳄梅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽戴尸。三九已至,卻和暖如春冤狡,著一層夾襖步出監(jiān)牢的瞬間孙蒙,已是汗流浹背项棠。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評論 1 274
  • 我被黑心中介騙來泰國打工挎峦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人坦胶。 一個月前我還...
    沈念sama閱讀 49,378評論 3 379
  • 正文 我出身青樓顿苇,卻偏偏與公主長得像,于是被迫代替她去往敵國和親讹语。 傳聞我的和親對象是個殘疾皇子蜂科,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,937評論 2 361

推薦閱讀更多精彩內(nèi)容