chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

二叉樹的前序遍歷非遞歸實現(xiàn)

算法與數(shù)據(jù)結(jié)構(gòu) ? 來源:袁廚的算法小屋 ? 作者:袁廚的算法小屋 ? 2021-05-28 13:59 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

我們之前說了二叉樹基礎(chǔ)及二叉的幾種遍歷方式及練習(xí)題,今天我們來看一下二叉樹的前序遍歷非遞歸實現(xiàn)。

前序遍歷的順序是, 對于樹中的某節(jié)點(diǎn),先遍歷該節(jié)點(diǎn),然后再遍歷其左子樹,最后遍歷其右子樹。

我們先來通過下面這個動畫復(fù)習(xí)一下二叉樹的前序遍歷。

迭代遍歷

我們試想一下,之前我們借助隊列幫我們實現(xiàn)二叉樹的層序遍歷,

那么可不可以,也借助數(shù)據(jù)結(jié)構(gòu),幫助我們實現(xiàn)二叉樹的前序遍歷。

假設(shè)我們的二叉樹為 [1,2,3]。我們需要對其進(jìn)行前序遍歷。其遍歷順序為

當(dāng)前節(jié)點(diǎn) 1,左孩子 2,右孩子 3。

這里可不可以用棧,幫我們完成前序遍歷呢?

棧和隊列的那些事

我們都知道棧的特性是先進(jìn)后出,我們借助棧來幫助我們完成前序遍歷的時候。

則需要注意的一點(diǎn)是,我們應(yīng)該先將右子節(jié)點(diǎn)入棧,再將左子節(jié)點(diǎn)入棧。

這樣出棧時,則會先出左節(jié)點(diǎn),再出右子節(jié)點(diǎn),則能夠完成樹的前序遍歷。

我們用一句話對上圖進(jìn)行總結(jié),當(dāng)棧不為空時,棧頂元素出棧,如果其右孩子不為空,則右孩子入棧,其左孩子不為空,則左孩子入棧。還有一點(diǎn)需要注意的是,我們和層序遍歷一樣,需要先將 root 節(jié)點(diǎn)進(jìn)行入棧,然后再執(zhí)行 while 循環(huán)。

看到這里你已經(jīng)能夠自己編寫出代碼了,不信你去試試。

時間復(fù)雜度:O(n) 需要對所有節(jié)點(diǎn)遍歷一次

空間復(fù)雜度:O(n) 棧的開銷,平均為 O(logn) 最快情況,即斜二叉樹時為 O(n)

參考代碼

class Solution {

public List《Integer》 preorderTraversal(TreeNode root) {

List《Integer》 list = new ArrayList《》();

Stack《TreeNode》 stack = new Stack《》();

if (root == null) return list;

stack.push(root);

while (!stack.isEmpty()) {

TreeNode temp = stack.pop();

if (temp.right != null) {

stack.push(temp.right);

}

if (temp.left != null) {

stack.push(temp.left);

}

//這里也可以放到前面

list.add(temp.val);

}

return list;

}

}

Morris

Morris 遍歷利用樹的左右孩子為空(大量空閑指針),實現(xiàn)空間開銷的極限縮減。這個遍歷方式,稍微有那么一丟丟難理解,不過結(jié)合動圖,也就一目了然,下面我們先看動畫吧。

看完視頻,是不是感覺自己搞懂了,又感覺自己沒搞懂,哈哈,咱們繼續(xù)往下看。

我們之前說的,Morris 遍歷利用了樹中大量空閑指針的特性,我們需要找到當(dāng)前節(jié)點(diǎn)的左子樹中的最右邊的葉子節(jié)點(diǎn),將該葉子節(jié)點(diǎn)的 right 指向當(dāng)前節(jié)點(diǎn)。例如當(dāng)前節(jié)點(diǎn)為2,其左子樹中的最右節(jié)點(diǎn)為 9 ,則在 9 節(jié)點(diǎn)添加一個 right 指針指向 2。

其實上圖中的 Morris 遍歷遵循兩個原則,我們在動畫中也能夠得出。

1.當(dāng) p1.left == null 時,p1 = p1.right。(這也就是我們?yōu)槭裁匆o葉子節(jié)點(diǎn)添加 right 指針的原因)

2.如果 p1.left != null,找到 p1 左子樹上最右的節(jié)點(diǎn)。(也就是我們的 p2 最后停留的位置),此時我們又可以分為兩種情況,一種是葉子節(jié)點(diǎn)添加 right 指針的情況,一種是去除葉子節(jié)點(diǎn) right 指針的情況。

如果 p2 的 right 指針指向空,讓其指向 p1,p1向左移動,即 p1 = p1.left

如果 p2 的 right 指針指向 p1,讓其指向空,(為了防止重復(fù)執(zhí)行,則需要去掉 right 指針)p1 向右移動,p1 = p1.right。

這時你可以結(jié)合咱們剛才提到的兩個原則,再去看一遍動畫,并代入規(guī)則進(jìn)行模擬,差不多就能完全搞懂啦。

下面我們來對動畫中的內(nèi)容進(jìn)行拆解

首先 p1 指向 root節(jié)點(diǎn)

p2 = p1.left,下面我們需要通過 p2 找到 p1的左子樹中的最右節(jié)點(diǎn)。即節(jié)點(diǎn) 5,然后將該節(jié)點(diǎn)的 right 指針指向 root。并記錄 root 節(jié)點(diǎn)的值。

向左移動 p1,即 p1 = p1.left

p2 = p1.left ,即節(jié)點(diǎn) 4 ,找到 p1 的左子樹中的最右葉子節(jié)點(diǎn),也就是 9,并將該節(jié)點(diǎn)的 right 指針指向 2。

繼續(xù)向左移動 p1,即 p1 = p1.left,p2 = p1.left。也就是節(jié)點(diǎn) 8。并將該節(jié)點(diǎn)的 right 指針指向 p1。

我們發(fā)現(xiàn)這一步給前兩步是一樣的,都是找到葉子節(jié)點(diǎn),將其 right 指針指向 p1,此時我們完成了添加 right 指針的過程,下面我們繼續(xù)往下看。

我們繼續(xù)移動 p1 指針,p1 = p1.left。p2 = p.left。此時我們發(fā)現(xiàn) p2 == null,即下圖此時我們需要移動 p1, 但是不再是 p1 = p1.left 而是 p1 = p1.right。也就是 4,繼續(xù)讓 p2 = p1.left。此時則為下圖這種情況

此時我們發(fā)現(xiàn) p2.right != null 而是指向 4,說明此時我們已經(jīng)添加過了 right 指針,所以去掉 right 指針,并讓 p1 = p1.right

下面則繼續(xù)移動 p1 ,按照規(guī)則繼續(xù)移動即可,遇到的情況已經(jīng)在上面做出了舉例,所以下面我們就不繼續(xù)贅述啦,如果還不是特別理解的同學(xué),可以再去看一遍動畫加深下印象。時間復(fù)雜度 O(n),空間復(fù)雜度 O(1)下面我們來看代碼吧。

代碼

class Solution {

public List《Integer》 preorderTraversal(TreeNode root) {

List《Integer》 list = new ArrayList《》();

if (root == null) {

return list;

}

TreeNode p1 = root; TreeNode p2 = null;

while (p1 != null) {

p2 = p1.left;

if (p2 != null) {

//找到左子樹的最右葉子節(jié)點(diǎn)

while (p2.right != null && p2.right != p1) {

p2 = p2.right;

}

//添加 right 指針,對應(yīng) right 指針為 null 的情況

if (p2.right == null) {

list.add(p1.val);

p2.right = p1;

p1 = p1.left;

continue;

}

//對應(yīng) right 指針存在的情況,則去掉 right 指針

p2.right = null;

} else {

list.add(p1.val);

}

//移動 p1

p1 = p1.right;

}

return list;

}

}

原文標(biāo)題:把二叉樹揉碎(二)

文章出處:【微信公眾號:算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

責(zé)任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 二叉樹
    +關(guān)注

    關(guān)注

    0

    文章

    74

    瀏覽量

    12893

原文標(biāo)題:把二叉樹揉碎(二)

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    TüV萊茵與杭集團(tuán)達(dá)成戰(zhàn)略合作并頒發(fā)歐盟CE-MD符合性證書

    日前,國際獨(dú)立第三方檢測、檢驗和認(rèn)證機(jī)構(gòu)德國萊茵TüV大中華區(qū)(簡稱"TüV萊茵")與杭集團(tuán)股份有限公司(簡稱"杭集團(tuán)")簽署了戰(zhàn)略合作協(xié)議,標(biāo)志著雙方
    的頭像 發(fā)表于 01-15 12:18 ?104次閱讀

    億緯鋰能與杭集團(tuán)達(dá)成戰(zhàn)略合作

    電器董事長金華曙,杭集團(tuán)董事單根生,杭集團(tuán)總經(jīng)理助理、杭電器總經(jīng)理李明輝出席儀式。雙方圍繞“技術(shù)共研、產(chǎn)能共建、場景共創(chuàng)”三大維度深化合作關(guān)系,促進(jìn)資源共享、優(yōu)勢互補(bǔ),
    的頭像 發(fā)表于 01-04 18:18 ?1018次閱讀

    C語言的常見算法

    = next; } return prev; } ``` ### 二叉樹遍歷 (前序) ```c struct TreeNode { int val; struct TreeNode
    發(fā)表于 11-24 08:29

    如何在AMD Vitis Unified IDE中使用系統(tǒng)設(shè)備

    您將在這篇博客中了解系統(tǒng)設(shè)備 (SDT) 以及如何在 AMD Vitis Unified IDE 中使用 SDT 維護(hù)來自 XSA 的硬件元數(shù)據(jù)。本文還講述了如何對 SDT 進(jìn)行操作,以便在 Vitis Unified IDE 中實現(xiàn)更靈活的使用場景。
    的頭像 發(fā)表于 11-18 11:13 ?3028次閱讀
    如何在AMD Vitis Unified IDE中使用系統(tǒng)設(shè)備<b class='flag-5'>樹</b>

    `lv_obj_tree.h` 在 **LVGL v9** 中的位置和作用

    /core/lv_obj_tree.h 核心作用 這個文件是 LVGL 核心模塊的一部分,主要負(fù)責(zé) UI 對象的管理,包括: 對象的父子關(guān)系維護(hù)(添加、刪除子對象); 對象遍歷(例如查找子對象、祖先
    發(fā)表于 11-13 15:49

    通過優(yōu)化代碼來提高M(jìn)CU運(yùn)行效率

    選擇時間復(fù)雜度低的算法。 根據(jù)訪問模式選擇數(shù)據(jù)結(jié)構(gòu)。頻繁查找用哈希表,有序數(shù)據(jù)用二叉樹等。 查表法:對于復(fù)雜的數(shù)學(xué)計算(如sin, log),或者協(xié)議解析,預(yù)先計算好結(jié)果存于數(shù)組中,用空間換時間
    發(fā)表于 11-12 08:21

    Verilog實現(xiàn)使用Booth編碼和Wallace的定點(diǎn)補(bǔ)碼乘法器原理

    對于有符號整數(shù)乘法操作,E203使用常用的Booth編碼產(chǎn)生部分積,然后使用迭代的方法,每個周期使用加法器對部分積進(jìn)行累加,經(jīng)過多個周期的迭代之后得到最終的乘積。其基本硬件原理圖如圖所示,從而實現(xiàn)
    發(fā)表于 10-23 08:01

    蜂鳥E203內(nèi)核中斷管理模塊sirv_plic_man代碼分析

    。 上面的代碼生成一個二叉樹結(jié)構(gòu)來比較和選擇具有最大優(yōu)先級的掛起中斷源及其ID。樹狀結(jié)構(gòu)由級聯(lián)比較器組成,每一層的比較器數(shù)量是前一層的一半。在的每一層,選擇優(yōu)先級最高的中斷并傳遞到下一層,直到只剩下
    發(fā)表于 10-23 06:05

    請問rtt studio 的文件夾打紅什么意思?

    rtt studio 的文件夾打紅什么意思?而且文件夾里面實際是有文件的,但是瀏覽不出來。
    發(fā)表于 09-18 06:34

    LABVIEW遞歸獲取列表顯示到樹形結(jié)構(gòu)

    我這個遞歸我邏輯沒問題啊!我斷點(diǎn)調(diào)試看了,是因為重入VI執(zhí)行沒有把樹形結(jié)構(gòu)里面節(jié)點(diǎn)傳入到下一個遞歸調(diào)用,進(jìn)入重調(diào)用的時候我看了樹形結(jié)構(gòu)里面節(jié)點(diǎn)是空的。第一次寫入的節(jié)點(diǎn)并沒有傳入到下一次遞歸。 反正很
    發(fā)表于 08-07 17:59

    億緯鋰能榮獲杭集團(tuán)2022-2024年度優(yōu)秀供應(yīng)商獎

    近日,億緯鋰能憑借卓越產(chǎn)品、可靠交付與優(yōu)質(zhì)服務(wù)榮獲杭集團(tuán)頒發(fā)的“2022-2024年度優(yōu)秀供應(yīng)商”獎。杭集團(tuán)副總經(jīng)理兼杭電器董事長金華曙、杭電器總經(jīng)理兼杭博電機(jī)總經(jīng)理李明輝出席
    的頭像 發(fā)表于 07-15 09:00 ?908次閱讀

    想在rtsmart中使用uart2,是不是只能通過修改設(shè)備方法來實現(xiàn)uart2的復(fù)用呀?

    我想在rtsmart中使用uart2,是不是只能通過修改設(shè)備方法來實現(xiàn)uart2的復(fù)用呀? 修改設(shè)備后如何只編譯設(shè)備文件? 編譯生成的文件可以直接替換到廬山派里嗎,具體替換路徑在
    發(fā)表于 06-24 07:04

    機(jī)器人看點(diǎn):宇科技王興興回上海母校 加速商業(yè)化落地 宇機(jī)器人手租賃火爆

    給大家?guī)硪恍C(jī)器人的消息: 宇科技王興興回上海母校 加速商業(yè)化落地 日前,宇科技創(chuàng)始人王興興在接受媒體專訪時候,介紹了公司的H1人形機(jī)器人的技術(shù)亮點(diǎn)及行業(yè)前景,H1人形機(jī)器人是首款能原地后翻出
    的頭像 發(fā)表于 02-25 11:26 ?1883次閱讀

    求解答,設(shè)備問題

    請問,rk3588j要再提取一個USB3.0接口設(shè)備怎么改
    發(fā)表于 02-20 11:22

    科技在物聯(lián)網(wǎng)方面

    據(jù)傳輸?shù)男枨?。例如,利?G的低延遲、高帶寬特性,實現(xiàn)機(jī)器人與云端服務(wù)器之間的快速數(shù)據(jù)傳輸,提高機(jī)器人的響應(yīng)速度和智能化水平。 智能決策與數(shù)據(jù)分析 邊緣計算與云計算結(jié)合:宇科技的機(jī)器人采用了邊緣
    發(fā)表于 02-04 06:48