刷穿劍指offer-Day22-樹I 樹的基礎(chǔ)知識講解!

樹的概念與名詞解釋

樹(Tree)是一種抽象的數(shù)據(jù)結(jié)構(gòu)丛楚,之所以把“它”叫做樹族壳,是因為它看起來像是一棵倒掛著的樹,即根在上趣些,葉朝下仿荆。

一棵樹是由n(n>=0)個元素組成的,當(dāng)n = 0時坏平,樹稱為空(null或empty)樹拢操。每個元素稱為一個節(jié)點(node),而最頂端的節(jié)點成為根節(jié)點舶替。

樹中的名詞和概念很多令境,在這里需要有個大概的了解:

名詞 解釋
父節(jié)點 若一個節(jié)點含有子節(jié)點,則這個節(jié)點稱為其子節(jié)點的父節(jié)點
子節(jié)點 一個節(jié)點含有的子樹的根節(jié)點稱為該節(jié)點的子節(jié)點
兄弟節(jié)點 具有相同父節(jié)點的節(jié)點互稱為兄弟節(jié)點
節(jié)點的層次 從根開始定義起顾瞪,根為第1層舔庶,根的子節(jié)點為第2層,以此類推
深度 對于任意節(jié)點n,n的深度為從根到n的唯一路徑長陈醒,根的深度為0
高度 對于任意節(jié)點n,n的高度為從n到一片樹葉的最長路徑長惕橙,所有樹葉的高度為0
堂兄弟節(jié)點 父節(jié)點在同一層的節(jié)點互為堂兄弟
節(jié)點的度 一個節(jié)點含有的子樹的個數(shù)稱為該節(jié)點的度
樹的度 一棵樹中,最大的節(jié)點度稱為樹的度

二叉樹

看到上面樹的度孵延,引出了我們算法中常見的一類樹結(jié)構(gòu) 二叉樹吕漂。所謂二叉樹,就是每個節(jié)點最多含有兩個子樹(左子樹和右子樹)的樹稱為二叉樹尘应。

而針對二叉樹的結(jié)構(gòu)與數(shù)據(jù)存儲又分為了以下幾種類型:

分類 特點
完全二叉樹 對于一棵二叉樹惶凝,假設(shè)其深度為d(d>1)吼虎,除了第d層外,其它各層的節(jié)點數(shù)目均已達最大值苍鲜,且第d層所有節(jié)點從左向右連續(xù)地緊密排列
滿二叉樹 二叉樹中所有非葉子結(jié)點的度都是2思灰,且葉子結(jié)點都在同一層次上
平衡二叉樹 當(dāng)且僅當(dāng)任何節(jié)點的兩棵子樹的高度差不大于1的二叉樹
二叉搜索樹 若它的左子樹不空,則左子樹上所有結(jié)點的值均小于它的根結(jié)點的值混滔;若它的右子樹不空洒疚,則右子樹上所有結(jié)點的值均大于它的根結(jié)點的值;

二叉樹的定義

一般而言坯屿,二叉樹的算法題目都是以鏈?zhǔn)酱鎯Φ姆蔷€性結(jié)構(gòu)油湖。力扣上涉及二叉樹的題目,都會默認定義好樹的結(jié)構(gòu)领跛,定義方式如下:

Python:

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

Java:

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

二叉樹的三種基礎(chǔ)遍歷

二叉樹的題目乏德,絕大多數(shù)都是在考樹的搜索。其中入門的是二叉樹的前吠昭、中喊括、后序遍歷:

  • 前序遍歷:遍歷順序規(guī)則為【根左右】
  • 中序遍歷:遍歷順序規(guī)則為【左根右】
  • 后序遍歷:遍歷順序規(guī)則為【左右根】

舉個例子:

  • 逐層遍歷:EAGCFBD
  • 前序遍歷:EACBDGF
  • 中序遍歷:ABCDEGF
  • 后序遍歷:BDCAFGE

逐層遍歷,其實就是上節(jié)課講解隊列的基礎(chǔ)操作時矢棚,涉及到的二叉樹的廣度優(yōu)先搜索郑什。剩下的三種遍歷方式,大家可以對照下是否和你想的結(jié)果一樣蒲肋。

那么蘑拯,我們該通過什么方式來實現(xiàn)二叉樹的遍歷操作呢?有遞歸 肉津、 迭代兩種方式强胰。

遞歸比較好理解,迭代又是什么妹沙?其實,遞歸的操作熟吏,是隱式的通過棧內(nèi)存完成遞歸距糖。而迭代則需要我們自己模擬棧內(nèi)存。讓我們拿一道題目來練練手吧牵寺。

144.二叉樹的前序遍歷

https://leetcode-cn.com/problems/binary-tree-preorder-traversal/

難度:簡單

題目

給你二叉樹的根節(jié)點 root 悍引,返回它節(jié)點值的 前序 遍歷。
提示:

  • 樹中節(jié)點數(shù)目在范圍 [0, 100] 內(nèi)
  • -100 <= Node.val <= 100

進階:遞歸算法很簡單帽氓,你可以通過迭代算法完成嗎趣斤?

示例

示例 1:
    1
     \
      2
    / 
   3  
輸入:root = [1,null,2,3]
輸出:[1,2,3]

分析

先來說說遞歸,使用遞歸的方式來完成前中后遍歷黎休,只需要修改遞歸函數(shù)的節(jié)點順序即可完成浓领。
牢記如下訪問順序即可玉凯。

  • 前序遍歷:遍歷順序規(guī)則為【根左右】
  • 中序遍歷:遍歷順序規(guī)則為【左根右】
  • 后序遍歷:遍歷順序規(guī)則為【左右根】

至于迭代,這需要我們將遞歸過程中隱式的內(nèi)存棧联贩,通過自己定義的方式來實現(xiàn)漫仆。
這里則要求我們,在掌握之前學(xué)習(xí)的鏈表和棧的操作基礎(chǔ)上泪幌,才更好理解這道題目盲厌。

  1. 首先,我們需要創(chuàng)建一個棧祸泪,然后創(chuàng)建cur節(jié)點指向root
  2. 然后當(dāng)椔鸷疲或者cur節(jié)點不為空時,啟動while循環(huán)操作
  3. 由于第一個入棧的是root節(jié)點没隘,則我們直接保存它的值
  4. 然后循環(huán)獲取當(dāng)前指針的左子樹指針(即cur.left)拓萌,保存值并加入棧中,直到指向葉子結(jié)點終止
  5. 之后彈出當(dāng)前棧升略,將指針指向cur.right繼續(xù)上述操作微王。
  6. 直到最終遍歷完成,返回節(jié)點的所有值品嚣。

讓我們來看看代碼的具體實現(xiàn)

遞歸解題

Python:

class Solution:
    def preorderTraversal(self, root):
        ret = []
        def dfs(tree):
            if not tree:
                return 
            if tree:
                ret.append(tree.val)
                dfs(tree.left)
                dfs(tree.right)
        dfs(root)
        return ret

Java:

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> ret = new ArrayList<>();
        dfs(root, ret);
        return ret;
    }

    private void dfs(TreeNode tree, List<Integer> ret){
        if (tree == null){
            return;
        }
        ret.add(tree.val);
        dfs(tree.left, ret);
        dfs(tree.right, ret);
    }
}

迭代解題

Python:

class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        ret = list()
        if not root:
            return ret

        stack = []
        cur = root
        while stack or cur:
            while cur:
                ret.append(cur.val)
                stack.append(cur)
                cur = cur.left
            cur = stack.pop()
            cur = cur.right
        return ret

Java:

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> ret = new ArrayList<Integer>();
        if (root == null) {
            return ret;
        }

        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while (!stack.isEmpty() || cur != null) {
            while (cur != null) {
                ret.add(cur.val);
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            cur = cur.right;
        }
        return ret;
    }
}

通過這道題炕倘,讓大家對二叉樹的遍歷有所了解,下來大家可以完成這兩道題目翰撑,用以加深了解罩旋。

今天的樹專題概念篇就到這里,明天就要正式開始刷題之旅了眶诈,基礎(chǔ)很重要一定要吃透了在往后走哦涨醋,明天見!

歡迎關(guān)注我的公眾號: 清風(fēng)Python逝撬,帶你每日學(xué)習(xí)Python算法刷題的同時浴骂,了解更多python小知識。

我的個人博客:https://qingfengpython.cn

力扣解題合集:https://github.com/BreezePython/AlgorithmMarkdown

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宪潮,一起剝皮案震驚了整個濱河市貌亭,隨后出現(xiàn)的幾起案子桶至,更是在濱河造成了極大的恐慌扰楼,老刑警劉巖褪迟,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異尽棕,居然都是意外死亡喳挑,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來伊诵,“玉大人单绑,你說我怎么就攤上這事∪崭辏” “怎么了询张?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長浙炼。 經(jīng)常有香客問我份氧,道長,這世上最難降的妖魔是什么弯屈? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任蜗帜,我火速辦了婚禮,結(jié)果婚禮上资厉,老公的妹妹穿的比我還像新娘厅缺。我一直安慰自己,他們只是感情好宴偿,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布湘捎。 她就那樣靜靜地躺著,像睡著了一般窄刘。 火紅的嫁衣襯著肌膚如雪窥妇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天娩践,我揣著相機與錄音活翩,去河邊找鬼。 笑死翻伺,一個胖子當(dāng)著我的面吹牛材泄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吨岭,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼拉宗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了未妹?” 一聲冷哼從身側(cè)響起簿废,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎络它,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體歪赢,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡化戳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片点楼。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡扫尖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出掠廓,到底是詐尸還是另有隱情换怖,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布蟀瞧,位于F島的核電站沉颂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏悦污。R本人自食惡果不足惜铸屉,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望切端。 院中可真熱鬧彻坛,春花似錦、人聲如沸踏枣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽茵瀑。三九已至间驮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瘾婿,已是汗流浹背蜻牢。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留偏陪,地道東北人抢呆。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像笛谦,于是被迫代替她去往敵國和親抱虐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

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