數(shù)據(jù)結(jié)構(gòu)與算法之二叉樹Binary Tree

樹Tree的基本概念
  • 節(jié)點(diǎn)、根節(jié)點(diǎn)炼鞠、父節(jié)點(diǎn)缘滥、子節(jié)點(diǎn)轰胁、兄弟節(jié)點(diǎn)
  • 一棵樹可以沒有任何節(jié)點(diǎn)谒主,稱為空樹
  • 一棵樹可以只有一個(gè)節(jié)點(diǎn),也就是只有根節(jié)點(diǎn)
  • 子樹赃阀、左子樹霎肯、右子樹

  • 節(jié)點(diǎn)的(degree):子樹的個(gè)數(shù)
    ??:1的度是5個(gè):2擎颖、3、4观游、5搂捧、6
    ??:2的度是2個(gè):2122
    ??:61的度是0個(gè)

  • 樹的(degree):所有節(jié)點(diǎn)度中的最大值
    ??:圖中最大的是節(jié)點(diǎn)1懂缕,有5個(gè)度

  • 葉子的節(jié)點(diǎn)(leaf):度為0的節(jié)點(diǎn)
    ??:圖中21允跑、221、222搪柑、223聋丝、31、5工碾、51弱睦、52、61都是葉子節(jié)點(diǎn)

  • 非葉子的節(jié)點(diǎn):度不為0的節(jié)點(diǎn)


  • 樹的層數(shù)(level):根節(jié)點(diǎn)在第1層渊额,根節(jié)點(diǎn)的子節(jié)點(diǎn)在第2層况木,以此類推(有些教程從第0層計(jì)算)

  • 節(jié)點(diǎn)的深度(depth):從根節(jié)點(diǎn)到當(dāng)前節(jié)點(diǎn)的唯一路勁上的節(jié)點(diǎn)總數(shù)
    ??:節(jié)點(diǎn)2的深度:從根節(jié)點(diǎn)12經(jīng)過了2個(gè)節(jié)點(diǎn),深度為2
    ??:節(jié)點(diǎn)31的深度:從根節(jié)點(diǎn)131經(jīng)過了3個(gè)節(jié)點(diǎn)旬迹,深度為3

  • 節(jié)點(diǎn)的高度(height):從當(dāng)前節(jié)點(diǎn)到最遠(yuǎn)葉子節(jié)點(diǎn)的路勁上的節(jié)點(diǎn)總數(shù)
    ??:節(jié)點(diǎn)2的高度:圖中看出從節(jié)點(diǎn)2到最遠(yuǎn)的葉子節(jié)點(diǎn)為221火惊、222、223中的一個(gè)奔垦,取其中一個(gè)計(jì)算矗晃,經(jīng)歷了2-22-221總共3個(gè)節(jié)點(diǎn),所有高度為3

  • 樹的深度:所有節(jié)點(diǎn)深度中的最大值

  • 樹的高度:所有節(jié)點(diǎn)高度中的最大值

  • 樹的深度 等于 樹的高度


有序樹宴倍、無序樹张症、森林
  • 有序樹:樹中的任意節(jié)點(diǎn)的子節(jié)點(diǎn)之間有順序關(guān)系
  • 有序樹:樹中的任意節(jié)點(diǎn)的子節(jié)點(diǎn)之間沒有順序關(guān)系(也稱為“自由樹”)
  • 森林:由 m (m >= 0) 棵互不相交的樹組成的集合

二叉樹Binary Tree

二叉樹的特點(diǎn):

  • 每個(gè)節(jié)點(diǎn)的度最大值為2(最多擁有2棵子樹)
  • 左子樹跟右子樹是有順序的
  • 即使某個(gè)節(jié)點(diǎn)只有一棵子樹,也要區(qū)分左右子樹
  • 二叉樹是有序樹

二叉樹的性質(zhì):

  • 非空二叉樹的第i層鸵贬,最多有 2i-1 個(gè)節(jié)點(diǎn)(i >= 1
  • 高度為h的二叉樹上最多有 2h-1 個(gè)節(jié)點(diǎn)(h>= 1
  • 對(duì)于任何一棵非空二叉樹俗他,如果葉子節(jié)點(diǎn)個(gè)數(shù)為n0,度為2的節(jié)點(diǎn)個(gè)數(shù)為n2阔逼,則有:n0 = n2 + 1
    假設(shè)度為1的節(jié)點(diǎn)個(gè)數(shù)為n1兆衅,那么二叉樹的節(jié)點(diǎn)總數(shù)n = n0 + n1 + n2
    二叉樹的變數(shù)T = n1 + 2 * n2 = n - 1 = n0 + n1 + n2 - 1

真二叉樹Proper Binary Tree
  • 所有節(jié)點(diǎn)的要么是0,要么是2

滿二叉樹Full Binary Tree
  • 所有節(jié)點(diǎn)的要么是0嗜浮,要么是2羡亩,且所有的葉子節(jié)點(diǎn)都在最后一層
  • 在同樣高度的二叉樹中,滿二叉樹的葉子節(jié)點(diǎn)數(shù)量最多危融,總節(jié)點(diǎn)數(shù)量最多
  • 滿二叉樹一定是真二叉樹畏铆,真二叉樹不一定是滿二叉樹
  • 假設(shè)滿二叉樹的高度為h(h>= 1),那么:
    ??:第i層的節(jié)點(diǎn)數(shù)量:2i-1
    ??:葉子節(jié)點(diǎn)數(shù)量:2h-1
    ??:總節(jié)點(diǎn)的數(shù)量n:n = 2h-1 = 20 + 21 + 22 + ... 2h-1

完全二叉樹Complete Binary Tree
  • 葉子節(jié)點(diǎn)只會(huì)出現(xiàn)在最后2層吉殃,且最后1層的葉子節(jié)點(diǎn)都靠左對(duì)齊
  • 完全二叉樹從根節(jié)點(diǎn)至倒數(shù)第2層是一棵滿二叉樹
  • 滿二叉樹一定是完全二叉樹辞居,完全二叉樹不一定是滿二叉樹
  • 度為1的節(jié)點(diǎn)只有左子樹
  • 度為1的節(jié)點(diǎn)要么是1個(gè)楷怒,要么是0個(gè)
  • 同樣節(jié)點(diǎn)數(shù)量的二叉樹,完全二叉樹的高度最小
  • 假設(shè)完全二叉樹的高度為h(h>= 1)瓦灶,那么:
    ??:至少有2h-1個(gè)節(jié)點(diǎn) 20 + 21 + 22 + ... 2h-2 + 1
    ??:最多有2h-1個(gè)節(jié)點(diǎn) 20 + 21 + 22 + ... 2h-1鸠删,滿二叉樹
    ??:總節(jié)點(diǎn)數(shù)量:2h-1<=n<=2h,取對(duì)數(shù):h - 1 <= log_2n < h

二叉搜索樹Binary Search Tree

1贼陶、二叉搜索樹是二叉樹的一種刃泡,是應(yīng)用非常廣泛的一種二叉樹,簡(jiǎn)稱BST

  • 又稱為:二叉查找樹碉怔、二叉排序樹
  • 任意一個(gè)節(jié)點(diǎn)的值都大于左子樹所有節(jié)點(diǎn)的值
  • 任意一個(gè)節(jié)點(diǎn)的值都小于右子樹所有節(jié)點(diǎn)的值
  • 它的左右子樹也是一顆二叉搜索樹

2捅僵、二叉搜索樹可以大大提高搜索數(shù)據(jù)的效率
3、二叉搜索樹存儲(chǔ)的元素必須具備可比較性

  • 比如 int眨层、double
  • 如果自定義類型庙楚,需要制定比較方式
  • 不允許為null

二叉樹的遍歷
  • 遍歷是數(shù)據(jù)結(jié)構(gòu)中常見操作:
    1??:把所有元素都訪問一遍
  • 線性數(shù)據(jù)結(jié)構(gòu)的遍歷比較簡(jiǎn)單:
    1??:正序遍歷
    2??:逆序遍歷
  • 根據(jù)節(jié)點(diǎn)訪問順序的不同,二叉樹的常見遍歷方式有4種:
    1??:前序遍歷
    2??:中序遍歷
    3??:后序遍歷
    4??:層序遍歷

二叉樹的遍歷 —— 前序遍歷
  • 訪問順序:
    ??:根節(jié)點(diǎn) — 前序遍歷左子樹 — 前序遍歷右子樹
    ??:7——4趴樱、2馒闷、1、3叁征、5——9纳账、8、11捺疼、10疏虫、12

可以利用遞歸來實(shí)

public void preporderTraversal() {
    preporderTraversal(rootNode);
}
private void preporderTraversal(Node<E> node) {
    if (node == null) { return; }
    System.out.println(node.element);
    preporderTraversal(node.leftNode);
    preporderTraversal(node.rightNode);
}

二叉樹的遍歷 —— 中序遍歷
  • 訪問順序:
    ??:中序遍歷左子樹根節(jié)點(diǎn) — 中序遍歷右子樹
    ??:1、2啤呼、3卧秘、4、5——7——8官扣、9翅敌、10、11惕蹄、12
  • 如果訪問順序是這樣的:
    ??:中序遍歷右子樹根節(jié)點(diǎn) — 中序遍歷左子樹
    ??:12蚯涮、11、10卖陵、9遭顶、8——7——5、4泪蔫、3棒旗、2、1
  • 二叉搜索樹的中序遍歷結(jié)果是升序或者降序的
public void inorderTraversal() {
    inorderTraversal(rootNode);
}
private void inorderTraversal(Node<E> node) {
    if (node == null) { return; }
    inorderTraversal(node.leftNode);
    System.out.println(node.element);
    inorderTraversal(node.rightNode);
}

二叉樹的遍歷 —— 后序遍歷
  • 訪問順序:
    ??:后序遍歷左子樹 — 后序遍歷右子樹根節(jié)點(diǎn)
    ??:1鸥滨、3嗦哆、2、5婿滓、4——8老速、10、12凸主、11橘券、9——7
public void postorderTraversal() {
    postorderTraversal(rootNode);
}
private void postorderTraversal(Node<E> node) {
    if (node == null) { return; }
    postorderTraversal(node.leftNode);
    postorderTraversal(node.rightNode);
    System.out.println(node.element);
}

二叉樹的遍歷 —— 層序遍歷
  • 訪問順序:
    ??:從上到下,從左到右依次訪問每一個(gè)節(jié)點(diǎn)
    ??:7——4卿吐、9——2旁舰、5、8嗡官、1——1箭窜、3、10衍腥、12
  • 實(shí)現(xiàn)思路:使用隊(duì)列
    1??:將根節(jié)點(diǎn)入隊(duì)
    2??:循環(huán)執(zhí)行下面操作磺樱,直到隊(duì)列為空:
    ??:將隊(duì)頭節(jié)點(diǎn)A出隊(duì),進(jìn)行訪問
    ??:將A的左子節(jié)點(diǎn)入隊(duì)
    ??:將A的右子節(jié)點(diǎn)入隊(duì)
public void levelOrderTraversal() {
    if (rootNode == null) { return; }
        
    Queue<Node<E>> queue = new LinkedList<>();
    queue.offer(rootNode);
        
    while (!queue.isEmpty()) {
        Node<E> node = queue.poll();
        System.out.println(node.element);
        //是否有左右子節(jié)點(diǎn)
        if (node.leftNode != null) {
            queue.offer(node.leftNode);
        }
        if (node.rightNode != null) {
            queue.offer(node.rightNode);
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末婆咸,一起剝皮案震驚了整個(gè)濱河市竹捉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌尚骄,老刑警劉巖块差,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異倔丈,居然都是意外死亡憨闰,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門需五,熙熙樓的掌柜王于貴愁眉苦臉地迎上來起趾,“玉大人,你說我怎么就攤上這事警儒⊙雕桑” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵蜀铲,是天一觀的道長(zhǎng)边琉。 經(jīng)常有香客問我,道長(zhǎng)记劝,這世上最難降的妖魔是什么变姨? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮厌丑,結(jié)果婚禮上定欧,老公的妹妹穿的比我還像新娘喻旷。我一直安慰自己,他們只是感情好轩拨,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布驶赏。 她就那樣靜靜地躺著,像睡著了一般爷辱。 火紅的嫁衣襯著肌膚如雪录豺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天饭弓,我揣著相機(jī)與錄音双饥,去河邊找鬼。 笑死弟断,一個(gè)胖子當(dāng)著我的面吹牛咏花,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播阀趴,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼迟螺,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了舍咖?” 一聲冷哼從身側(cè)響起矩父,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎排霉,沒想到半個(gè)月后窍株,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡攻柠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年球订,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瑰钮。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡冒滩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出浪谴,到底是詐尸還是另有隱情开睡,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布苟耻,位于F島的核電站篇恒,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏凶杖。R本人自食惡果不足惜胁艰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧腾么,春花似錦奈梳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至饭寺,卻和暖如春阻课,著一層夾襖步出監(jiān)牢的瞬間叫挟,已是汗流浹背艰匙。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抹恳,地道東北人员凝。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像奋献,于是被迫代替她去往敵國和親健霹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354