日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

6-4 二叉树的非递归遍历 (25分)_本周小结!(二叉树)

發(fā)布時(shí)間:2024/7/19 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 6-4 二叉树的非递归遍历 (25分)_本周小结!(二叉树) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
給「代碼隨想錄」一個(gè)星標(biāo)吧!?

以后每周加上一個(gè)本周小結(jié)怎么樣?

?

本周小結(jié)

發(fā)現(xiàn)大家周末的時(shí)候貌似都不在學(xué)習(xí)狀態(tài),周末的文章瀏覽量和打卡情況照工作日差很多呀,可能是本周日是工作日了,周六得好好放松放松,哈哈,理解理解,但我還不能不更啊,還有同學(xué)要看呢。

所以呢,「周日我做一個(gè)針對(duì)本周的打卡留言疑問以及在刷題群里的討論內(nèi)容做一下梳理吧。」,這樣也有助于大家補(bǔ)一補(bǔ)本周的內(nèi)容,消化消化。

「注意這個(gè)周末總結(jié)和系列總結(jié)還是不一樣的(二叉樹還遠(yuǎn)沒有結(jié)束),這個(gè)總結(jié)是針對(duì)留言疑問以及刷題群里討論內(nèi)容的歸納。」

周一

本周我們開始講解了二叉樹,在關(guān)于二叉樹,你該了解這些!中講解了二叉樹的理論基礎(chǔ)。

有同學(xué)會(huì)把紅黑樹和二叉平衡搜索樹弄分開了,其實(shí)紅黑樹就是一種二叉平衡搜索樹,這兩個(gè)樹不是獨(dú)立的,所以C++中map、multimap、set、multiset的底層實(shí)現(xiàn)機(jī)制是二叉平衡搜索樹,再具體一點(diǎn)是紅黑樹。

對(duì)于二叉樹節(jié)點(diǎn)的定義,C++代碼如下:

struct?TreeNode?{
????int?val;
????TreeNode?*left;
????TreeNode?*right;
????TreeNode(int?x)?:?val(x),?left(NULL),?right(NULL)?{}
};

對(duì)于這個(gè)定義中TreeNode(int x) : val(x), left(NULL), right(NULL) {} 有同學(xué)不清楚干什么的。

這是構(gòu)造函數(shù),這么說吧C語言中的結(jié)構(gòu)體是C++中類的祖先,所以C++結(jié)構(gòu)體也可以有構(gòu)造函數(shù)。

構(gòu)造函數(shù)也可以不寫,但是new一個(gè)新的節(jié)點(diǎn)的時(shí)候就比較麻煩。

例如有構(gòu)造函數(shù),定義初始值為9的節(jié)點(diǎn):

TreeNode*?a?=?new?TreeNode(9);

沒有構(gòu)造函數(shù)的話就要這么寫:

TreeNode*?a?=?new?TreeNode();?
a->val?=?9;?
a->left?=?NULL;
a->right?=?NULL;??

在介紹前中后序遍歷的時(shí)候,有遞歸和迭代(非遞歸),還有一種牛逼的遍歷方式:morris遍歷。

morris遍歷是二叉樹遍歷算法的超強(qiáng)進(jìn)階算法,morris遍歷可以將非遞歸遍歷中的空間復(fù)雜度降為O(1),感興趣大家就去查一查學(xué)習(xí)學(xué)習(xí),比較小眾,面試幾乎不會(huì)考。我其實(shí)也沒有研究過,就不做過多介紹了。

周二

在二叉樹:一入遞歸深似海,從此offer是路人中講到了遞歸三要素,以及前中后序的遞歸寫法。

文章中我給出了leetcode上三道二叉樹的前中后序題目,但是看完二叉樹:一入遞歸深似海,從此offer是路人,依然可以解決n叉樹的前后序遍歷,在leetcode上分別是

  • 589 . N叉樹的前序遍歷
  • 590 . N叉樹的后序遍歷

大家可以再去把這兩道題目做了。

周三

在二叉樹:聽說遞歸能做的,棧也能做!中我們開始用棧來實(shí)現(xiàn)遞歸的寫法,也就是所謂的迭代法。

細(xì)心的同學(xué)發(fā)現(xiàn)文中前后序遍歷空節(jié)點(diǎn)是入棧的,其實(shí)空節(jié)點(diǎn)入不入棧都差不多,但感覺空節(jié)點(diǎn)不入棧確實(shí)清晰一些,符合文中動(dòng)畫的演示。

前序遍歷空節(jié)點(diǎn)不入棧的代碼:(注意注釋部分,和文章中的區(qū)別)

class?Solution?{
public:
????vector?preorderTraversal(TreeNode*?root)?{
????????stack?st;
????????vector?result;if?(root?==?NULL)?return?result;
????????st.push(root);while?(!st.empty())?{
????????????TreeNode*?node?=?st.top();???????????????????????//?中
????????????st.pop();
????????????result.push_back(node->val);if?(node->right)?st.push(node->right);???????????//?右(空節(jié)點(diǎn)不入棧)if?(node->left)?st.push(node->left);?????????????//?左(空節(jié)點(diǎn)不入棧)
????????}return?result;
????}
};

后序遍歷空節(jié)點(diǎn)不入棧的代碼:(注意注釋部分,和文章中的區(qū)別)

class?Solution?{
public:
????vector?postorderTraversal(TreeNode*?root)?{
????????stack?st;
????????vector?result;if?(root?==?NULL)?return?result;
????????st.push(root);while?(!st.empty())?{
????????????TreeNode*?node?=?st.top();
????????????st.pop();
????????????result.push_back(node->val);if?(node->left)?st.push(node->left);?//?相對(duì)于前序遍歷,這更改一下入棧順序?(空節(jié)點(diǎn)不入棧)if?(node->right)?st.push(node->right);?//?空節(jié)點(diǎn)不入棧
????????}
????????reverse(result.begin(),?result.end());?//?將結(jié)果反轉(zhuǎn)之后就是左右中的順序了return?result;
????}
};

在實(shí)現(xiàn)迭代法的過程中,有同學(xué)問了:遞歸與迭代究竟誰優(yōu)誰劣呢?

從時(shí)間復(fù)雜度上其實(shí)迭代法和遞歸法差不多(在不考慮函數(shù)調(diào)用開銷和函數(shù)調(diào)用產(chǎn)生的堆棧開銷),但是空間復(fù)雜度上,遞歸開銷會(huì)大一些,因?yàn)檫f歸需要系統(tǒng)堆棧存參數(shù)返回值等等。

遞歸更容易讓程序員理解,但收斂不好,容易棧溢出。

這么說吧,遞歸是方便了程序員,難為了機(jī)器(各種保存參數(shù),各種進(jìn)棧出棧)。

「在實(shí)際項(xiàng)目開發(fā)的過程中我們是要盡量避免遞歸!因?yàn)轫?xiàng)目代碼參數(shù)、調(diào)用關(guān)系都比較復(fù)雜,不容易控制遞歸深度,甚至?xí)R绯觥!?/strong>

周四

在二叉樹:前中后序迭代方式的寫法就不能統(tǒng)一一下么?中我們使用空節(jié)點(diǎn)作為標(biāo)記,給出了統(tǒng)一的前中后序迭代法。

此時(shí)又多了一種前中后序的迭代寫法,那么有同學(xué)問了:前中后序迭代法是不是一定要統(tǒng)一來寫,這樣才算是規(guī)范。

其實(shí)沒必要,還是自己感覺哪一種更好記就用哪種。

但是「一定要掌握前中后序一種迭代的寫法,并不因?yàn)槟撤N場景的題目一定要用迭代,而是現(xiàn)場面試的時(shí)候,面試官看你順暢的寫出了遞歸,一般會(huì)進(jìn)一步考察能不能寫出相應(yīng)的迭代。」

周五

在二叉樹:層序遍歷登場!中我們介紹了二叉樹的另一種遍歷方式(圖論中廣度優(yōu)先搜索在二叉樹上的應(yīng)用)即:層序遍歷。

看完這篇文章,去leetcode上怒刷五題,文章中 編號(hào)107題目的樣例圖放錯(cuò)了(原諒我匆忙之間總是手抖),但不影響大家理解。

只有同學(xué)發(fā)現(xiàn)leetcode上“515. 在每個(gè)樹行中找最大值”,也是層序遍歷的應(yīng)用,依然可以分分鐘解決,所以就是一鼓作氣解決六道了,哈哈。

「層序遍歷遍歷相對(duì)容易一些,只要掌握基本寫法(也就是框架模板),剩下的就是在二叉樹每一行遍歷的時(shí)候做做邏輯修改。」

周六

在二叉樹:你真的會(huì)翻轉(zhuǎn)二叉樹么?中我們把翻轉(zhuǎn)二叉樹這么一道簡單又經(jīng)典的問題,充分的剖析了一波,相信就算做過這道題目的同學(xué),看完本篇之后依然有所收獲!

「文中我指的是遞歸的中序遍歷是不行的,因?yàn)槭褂眠f歸的中序遍歷,某些節(jié)點(diǎn)的左右孩子會(huì)翻轉(zhuǎn)兩次。」

如果非要使用遞歸的中序的方式寫,也可以,如下代碼就可以避免節(jié)點(diǎn)左右孩子翻轉(zhuǎn)兩次的情況:

class?Solution?{
public:
????TreeNode*?invertTree(TreeNode*?root)?{
????????if?(root?==?NULL)?return?root;
????????invertTree(root->left);?????????//?左
????????swap(root->left,?root->right);??//?中
????????invertTree(root->left);?????????//?注意?這里依然要遍歷左孩子,因?yàn)橹虚g節(jié)點(diǎn)已經(jīng)翻轉(zhuǎn)了
????????return?root;
????}
};

代碼雖然可以,但這畢竟不是真正的遞歸中序遍歷了。

但使用迭代方式統(tǒng)一寫法的中序是可以的。

代碼如下:

class?Solution?{
public:
????TreeNode*?invertTree(TreeNode*?root)?{
????????stack?st;if?(root?!=?NULL)?st.push(root);while?(!st.empty())?{
????????????TreeNode*?node?=?st.top();if?(node?!=?NULL)?{
????????????????st.pop();if?(node->right)?st.push(node->right);??//?右
????????????????st.push(node);??????????????????????????//?中
????????????????st.push(NULL);if?(node->left)?st.push(node->left);????//?左
????????????}?else?{
????????????????st.pop();
????????????????node?=?st.top();
????????????????st.pop();
????????????????swap(node->left,?node->right);??????????//?節(jié)點(diǎn)處理邏輯
????????????}
????????}return?root;
????}
};

為什么這個(gè)中序就是可以的呢,因?yàn)檫@是用棧來遍歷,而不是靠指針來遍歷,避免了遞歸法中翻轉(zhuǎn)了兩次的情況,大家可以畫圖理解一下,這里有點(diǎn)意思的。

總結(jié)

「本周我們都是講解了二叉樹,從理論基礎(chǔ)到遍歷方式,從遞歸到迭代,從深度遍歷到廣度遍歷,最后再用了一個(gè)翻轉(zhuǎn)二叉樹的題目把我們之前講過的遍歷方式都串了起來。」

下周依然是二叉樹,大家加油!

在留言區(qū)留下你的思路吧!

-------end-------

我將算法學(xué)習(xí)相關(guān)的資料已經(jīng)整理到了Github :https://github.com/youngyangyang04/leetcode-master,里面還有l(wèi)eetcode刷題攻略、各個(gè)類型經(jīng)典題目刷題順序、思維導(dǎo)圖看一看一定會(huì)有所收獲,如果給你有幫助給一個(gè)star支持一下吧!

另外因?yàn)楣娞?hào)改版,時(shí)間線被打亂,一些精彩文章大家可能錯(cuò)過了。如果感覺這里的文章對(duì)你有幫助,趕緊給「代碼隨想錄」加一個(gè)星標(biāo)吧,方便第一時(shí)間閱讀文章往期精彩回顧二叉樹:你真的會(huì)翻轉(zhuǎn)二叉樹么?二叉樹:層序遍歷登場!二叉樹:前中后序迭代方式的寫法就不能統(tǒng)一一下么?二叉樹:聽說遞歸能做的,棧也能做!二叉樹:一入遞歸深似海,從此offer是路人關(guān)于二叉樹,你該了解這些!「代碼隨想錄」期待你的關(guān)注!

每天8:35準(zhǔn)時(shí)推送一道經(jīng)典算法題目,推送的每道題目都不是孤立的,而是由淺入深,環(huán)環(huán)相扣,幫你梳理算法知識(shí)脈絡(luò),輕松學(xué)算法!

刷題可以加我微信!右邊為個(gè)人微信,添加時(shí)備注:「簡單自我介紹」+「組隊(duì)刷題」我就知道你[在看]

總結(jié)

以上是生活随笔為你收集整理的6-4 二叉树的非递归遍历 (25分)_本周小结!(二叉树)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。