自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

二叉樹(shù):一入遞歸深似海,從此offer是路人

開(kāi)發(fā) 前端
「本篇將介紹前后中序的遞歸寫(xiě)法,一些同學(xué)可能會(huì)感覺(jué)很簡(jiǎn)單,其實(shí)不然,我們要通過(guò)簡(jiǎn)單題目把方法論確定下來(lái),有了方法論,后面才能應(yīng)付復(fù)雜的遞歸。」

[[351363]]

 ❝一看就會(huì),一寫(xiě)就廢!❞

這次我們要好好談一談遞歸,為什么很多同學(xué)看遞歸算法都是“一看就會(huì),一寫(xiě)就廢”。

主要是對(duì)遞歸不成體系,沒(méi)有方法論,「每次寫(xiě)遞歸算法 ,都是靠玄學(xué)來(lái)寫(xiě)代碼」,代碼能不能編過(guò)都靠運(yùn)氣。

「本篇將介紹前后中序的遞歸寫(xiě)法,一些同學(xué)可能會(huì)感覺(jué)很簡(jiǎn)單,其實(shí)不然,我們要通過(guò)簡(jiǎn)單題目把方法論確定下來(lái),有了方法論,后面才能應(yīng)付復(fù)雜的遞歸?!?/p>

這里幫助大家確定下來(lái)遞歸算法的三個(gè)要素?!该看螌?xiě)遞歸,都按照這三要素來(lái)寫(xiě),可以保證大家寫(xiě)出正確的遞歸算法!」

  1. 「確定遞歸函數(shù)的參數(shù)和返回值:」確定哪些參數(shù)是遞歸的過(guò)程中需要處理的,那么就在遞歸函數(shù)里加上這個(gè)參數(shù), 并且還要明確每次遞歸的返回值是什么進(jìn)而確定遞歸函數(shù)的返回類(lèi)型。
  2. 「確定終止條件:」寫(xiě)完了遞歸算法, 運(yùn)行的時(shí)候,經(jīng)常會(huì)遇到棧溢出的錯(cuò)誤,就是沒(méi)寫(xiě)終止條件或者終止條件寫(xiě)的不對(duì),操作系統(tǒng)也是用一個(gè)棧的結(jié)構(gòu)來(lái)保存每一層遞歸的信息,如果遞歸沒(méi)有終止,操作系統(tǒng)的內(nèi)存棧必然就會(huì)溢出。
  3. 「確定單層遞歸的邏輯:」確定每一層遞歸需要處理的信息。在這里也就會(huì)重復(fù)調(diào)用自己來(lái)實(shí)現(xiàn)遞歸的過(guò)程。

好了,我們確認(rèn)了遞歸的三要素,接下來(lái)就來(lái)練練手:

「以下以前序遍歷為例:」

「確定遞歸函數(shù)的參數(shù)和返回值」:因?yàn)橐蛴〕銮靶虮闅v節(jié)點(diǎn)的數(shù)值,所以參數(shù)里需要傳入vector在放節(jié)點(diǎn)的數(shù)值,除了這一點(diǎn)就不需要在處理什么數(shù)據(jù)了也不需要有返回值,所以遞歸函數(shù)返回類(lèi)型就是void,代碼如下:

  1. void traversal(TreeNode* cur, vector<int>& vec) 

「確定終止條件」:在遞歸的過(guò)程中,如何算是遞歸結(jié)束了呢,當(dāng)然是當(dāng)前遍歷的節(jié)點(diǎn)是空了,那么本層遞歸就要要結(jié)束了,所以如果當(dāng)前遍歷的這個(gè)節(jié)點(diǎn)是空,就直接return,代碼如下:

  1. if (cur == NULLreturn

「確定單層遞歸的邏輯」:前序遍歷是中左右的循序,所以在單層遞歸的邏輯,是要先取中節(jié)點(diǎn)的數(shù)值,代碼如下:

  1. vec.push_back(cur->val);    // 中 
  2. traversal(cur->left, vec);  // 左 
  3. traversal(cur->right, vec); // 右 

單層遞歸的邏輯就是按照中左右的順序來(lái)處理的,這樣二叉樹(shù)的前序遍歷,基本就寫(xiě)完了,在看一下完整代碼:

前序遍歷:

  1. class Solution { 
  2. public
  3.     void traversal(TreeNode* cur, vector<int>& vec) { 
  4.         if (cur == NULLreturn
  5.         vec.push_back(cur->val);    // 中 
  6.         traversal(cur->left, vec);  // 左 
  7.         traversal(cur->right, vec); // 右 
  8.     } 
  9.     vector<int> preorderTraversal(TreeNode* root) { 
  10.         vector<int> result; 
  11.         traversal(root, result); 
  12.         return result; 
  13.     } 
  14. }; 

那么前序遍歷寫(xiě)出來(lái)之后,中序和后序遍歷就不難理解了,代碼如下:

中序遍歷:

  1. void traversal(TreeNode* cur, vector<int>& vec) { 
  2.        if (cur == NULLreturn
  3.        traversal(cur->left, vec);  // 左 
  4.        vec.push_back(cur->val);    // 中 
  5.        traversal(cur->right, vec); // 右 
  6.    } 

后序遍歷:

  1. void traversal(TreeNode* cur, vector<int>& vec) { 
  2.         if (cur == NULLreturn
  3.         traversal(cur->left, vec);  // 左 
  4.         traversal(cur->right, vec); // 右 
  5.         vec.push_back(cur->val);    // 中 
  6.     } 

此時(shí)大家可以做一做leetcode上三道題目,分別是:

  • 144.二叉樹(shù)的前序遍歷
  • 145.二叉樹(shù)的后序遍歷
  • 94.二叉樹(shù)的中序遍歷

可能有同學(xué)感覺(jué)前后中序遍歷的遞歸太簡(jiǎn)單了,要打迭代法(非遞歸),別急,我們明天打前中后序的迭代法,打個(gè)通透!

本文轉(zhuǎn)載自微信公眾號(hào)「代碼隨想錄」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系代碼隨想錄公眾號(hào)。

 

責(zé)任編輯:武曉燕 來(lái)源: 代碼隨想錄
相關(guān)推薦

2018-09-04 10:39:40

開(kāi)發(fā)

2020-04-27 07:05:58

二叉樹(shù)左子樹(shù)右子樹(shù)

2021-05-06 17:46:30

二叉樹(shù)數(shù)據(jù)結(jié)構(gòu)

2021-09-15 07:40:50

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

2021-04-19 07:47:42

數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)Tree

2021-04-20 08:37:14

數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)樹(shù)

2021-09-29 10:19:00

算法平衡二叉樹(shù)

2021-12-17 14:26:58

二叉樹(shù)節(jié)點(diǎn)數(shù)量

2021-03-17 08:19:22

二叉樹(shù)LeetCode樹(shù)

2013-07-15 16:35:55

二叉樹(shù)迭代器

2021-08-06 11:34:05

二叉樹(shù)遞歸回溯

2021-07-13 11:32:41

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

2020-09-23 18:25:40

算法二叉樹(shù)多叉樹(shù)

2021-04-28 20:12:27

數(shù)據(jù)結(jié)構(gòu)創(chuàng)建

2022-10-12 23:25:17

二叉樹(shù)父節(jié)點(diǎn)根節(jié)點(diǎn)

2021-03-22 08:23:29

LeetCode二叉樹(shù)節(jié)點(diǎn)

2021-08-27 11:36:44

二叉樹(shù)回溯節(jié)點(diǎn)

2023-05-08 15:57:16

二叉樹(shù)數(shù)據(jù)結(jié)構(gòu)

2021-11-29 10:40:58

二叉樹(shù)鏡像節(jié)點(diǎn)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)