二叉搜索樹(BST)、平衡二叉搜索樹

背景

我們認(rèn)為線性數(shù)據(jù)結(jié)構(gòu)包括:Vector(理解為數(shù)組)捌袜、List(理解為鏈表)说搅、棧、隊(duì)列虏等,半線性結(jié)構(gòu)包括:樹弄唧、二叉樹。

線性結(jié)構(gòu)無法兼顧查找霍衫、插入操作候引,它們要么查找很慢、要么插入很慢敦跌,所以我們引入搜索樹這種半線性結(jié)構(gòu)澄干,希望能兼顧查找和搜索操作。

數(shù)據(jù)結(jié)構(gòu) 查找最差 插入最差 備注
無序數(shù)組 O(N) O(N) 或 O(1) 注1
有序數(shù)組 O(logN) O(N)
鏈表 O(N) O(1)
二叉搜索樹 O(N) O(N)
平衡二叉搜索樹 O(logN) O(logN)

注1:若采用翻倍擴(kuò)容策略柠傍,則插入的分?jǐn)倳r(shí)間復(fù)雜度為O(1)麸俘,對(duì)本文來說可不必理解那么深入。

雖然二叉搜索樹(BST)的查找携兵、插入操作最壞時(shí)間復(fù)雜度為O(N)疾掰,不甚理想。但在BST的思想基礎(chǔ)上稍加改進(jìn)徐紧,就可以得到平衡二叉搜索樹(BBST)静檬,BBST的查找、插入都是O(logN)并级。BBST有很多種:AVL拂檩、紅黑樹等,本文介紹其中最簡單的AVL嘲碧。

BST的定義和性質(zhì)

BST的順序性:

  • 左子樹的所有節(jié)點(diǎn) <= 當(dāng)前節(jié)點(diǎn)
  • 右子樹的所有節(jié)點(diǎn) >= 當(dāng)前節(jié)點(diǎn)

由BST的順序性可以引申/推導(dǎo)出幾個(gè)結(jié)論:

  • BST的中序遍歷序列必然單調(diào)稻励,見圖(copy自鄧俊輝數(shù)據(jù)結(jié)構(gòu))
BST的中序遍歷序列

BST的實(shí)現(xiàn)

BST的查找、插入操作是容易的,本文略去不介紹望抽。

而對(duì)于BST的節(jié)點(diǎn)刪除操作加矛,并不是很簡單,需要分幾種情況煤篙。

  1. 待刪節(jié)點(diǎn)為葉子
  2. 待刪節(jié)點(diǎn)只有左孩子或右孩子
  3. 待刪節(jié)點(diǎn)既有左孩子又有右孩子斟览,通過將待刪節(jié)點(diǎn)及其「直接后繼」進(jìn)行交換,從而轉(zhuǎn)為情況2辑奈,直接后繼是指中序遍歷的下一個(gè)節(jié)點(diǎn)苛茂,如圖(copy自鄧俊輝數(shù)據(jù)結(jié)構(gòu))。
情況3轉(zhuǎn)為情況2的處理方法

情況1鸠窗、2雖然簡單妓羊,但代碼實(shí)現(xiàn)有點(diǎn)小麻煩。這里你會(huì)發(fā)現(xiàn)C稍计、C++的指針躁绸、引用是那么好用啊丙猬!反倒是Python涨颜、Java實(shí)現(xiàn)起來很難受费韭。不信我們以情況1為例考察下面不同語言的代碼茧球。

# Python語言
def remove(x):
    if x.left is None and x.right is None:  # 情況1
        # 這里麻煩,不但要依賴parent星持,還要判斷自己是左孩子or右孩子
        if x == x.parent.left:
            x.parent.left = None
        else:
            x.parent.right = None
// C++語言抢埋,讓調(diào)用者傳入指針的引用
void remove(TreeNode *&x) {
    if (x->left == NULL && x->right == NULL) {  // 情況1
        x = NULL;  // 這里就特別方便了
    }
}

若不斷插入已經(jīng)升序/降序的元素,BST會(huì)達(dá)到最差情況督暂,此時(shí)BST是極不平衡的揪垄。如圖(copy自鄧俊輝數(shù)據(jù)結(jié)構(gòu))。


image.png

平衡二叉搜索樹:AVL

為了克服BST的最差情況逻翁,我們引入AVL饥努。
todo:剩下內(nèi)容后續(xù)補(bǔ)充,不過我有拖延癥八回。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末酷愧,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子缠诅,更是在濱河造成了極大的恐慌溶浴,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件管引,死亡現(xiàn)場離奇詭異士败,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)褥伴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門谅将,熙熙樓的掌柜王于貴愁眉苦臉地迎上來漾狼,“玉大人,你說我怎么就攤上這事饥臂“钔叮” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵擅笔,是天一觀的道長志衣。 經(jīng)常有香客問我,道長猛们,這世上最難降的妖魔是什么念脯? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮弯淘,結(jié)果婚禮上绿店,老公的妹妹穿的比我還像新娘。我一直安慰自己庐橙,他們只是感情好假勿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著态鳖,像睡著了一般转培。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上浆竭,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天浸须,我揣著相機(jī)與錄音,去河邊找鬼邦泄。 笑死删窒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的顺囊。 我是一名探鬼主播肌索,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼特碳!你這毒婦竟也來了诚亚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤测萎,失蹤者是張志新(化名)和其女友劉穎亡电,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體硅瞧,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡份乒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片或辖。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瘾英,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出颂暇,到底是詐尸還是另有隱情缺谴,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布耳鸯,位于F島的核電站湿蛔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏县爬。R本人自食惡果不足惜阳啥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望财喳。 院中可真熱鬧察迟,春花似錦、人聲如沸耳高。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽泌枪。三九已至概荷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間工闺,已是汗流浹背乍赫。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留陆蟆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓惋增,卻偏偏與公主長得像叠殷,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子诈皿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348