成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

二叉樹的遞歸和非遞歸的遍歷算法模板

開發 前端 算法
二叉樹的四種遍歷方式,前中后加上層序遍歷。對于二叉樹的前中后層序遍歷,每種遍歷都可以遞歸和循環兩種實現方法,且每種遍歷的遞歸實現都比循環實現要簡潔。

[[423968]]

刷Leetcode,需要知道一定的算法模板,本次先總結下二叉樹的遞歸和非遞歸的遍歷算法模板。

二叉樹的四種遍歷方式,前中后加上層序遍歷。對于二叉樹的前中后層序遍歷,每種遍歷都可以遞歸和循環兩種實現方法,且每種遍歷的遞歸實現都比循環實現要簡潔。下面做一個小結,看了《代碼隨想錄》哈工大大佬的刷題指南,深受啟發,因,下面代碼有一定來源《代碼隨想錄》。

遞歸

下面偽代碼是二叉樹遍歷的遞歸算法模板,順序是中左右,也就是前序遍歷,改變中左右三行代碼的順序,前中后序三種遞歸遍歷輕松解決。

  1. def preorderTraversal(root: TreeNode) -> List[int]: 
  2.     res = [] 
  3.     def help(root): 
  4.         if not root: return 
  5.         res.append(root.val) # 中 
  6.         help(root.left) # 左 
  7.         help(root.right) # 右 
  8.     help(root) 
  9.     return res 

對此也提供C++代碼,遞歸算法模板一定要加上終止條件,不然一入遞歸深似海,從此offer是路人,來源代碼隨想錄。

  1. void help(TreeNode * root , vector<int> &res) { 
  2.     if (root == nullptr) { 
  3.         return
  4.     } 
  5.     res.push_back(root->val); // 中 
  6.     help(root->left,res); // 左 
  7.     help(root->right,res); //右 
  8.  
  9.  
  10. vector<int> preorderTraversal(TreeNode* root) { 
  11.     vector<int> res; 
  12.     help(root,res); 
  13.     return res; 

迭代

迭代遍歷二叉樹的比遞歸難度加大,其實使用了一個棧的數據結構,《代碼隨想錄》非常巧妙的使用空指針來作標記,原理是將處理的節點放入棧之后,緊接著放入一個空指針作為標記。

由于棧是先進后出,所以前序遍歷的順序中左右,在加到棧中,需要反過來進行添加,每添加一個元素在后面添加一個空指針,在Python中也可以使用None來代替。

下面是具體的偽代碼,至于中序和后序遍歷,改下向棧中添加節點的順序即可。

  1. def preorderTraversal(root: TreeNode) -> List[int]: 
  2.       result = [] 
  3.       st= [] 
  4.       # 1、判斷root 
  5.       if root: 
  6.           st.append(root) 
  7.       while st: 
  8.           node = st.pop() 
  9.           if node != None: 
  10.               # 右左中 添加到棧中,然后中左右拿出 
  11.               if node.right: #右 
  12.                   st.append(node.right
  13.               if node.left: #左 
  14.                   st.append(node.left
  15.               st.append(node) #中 
  16.               # 添加一個空指針 記錄節點 
  17.               st.append(None) 
  18.           else:  
  19.              # node是空指針,那么下一個就是加入的節點 
  20.               node = st.pop() 
  21.               result.append(node.val) 
  22.       return result 

下面是具體的C++代碼,由于C++中的stack中pop之后,沒有返回值,因此需要額外注意。

  1. vector<int> preorderTraversal(TreeNode* root) { 
  2.         vector<int>res; 
  3.         stack<TreeNode*> st; 
  4.         if (root != nullptr) st.push(root); 
  5.         while(!st.empty()){ 
  6.             TreeNode* node = st.top(); 
  7.             if(node != nullptr){ 
  8.                 st.pop(); 
  9.                 if(node->right) st.push(node->right); 
  10.                 if (node->left) st.push(node->left); 
  11.                 st.push(node); 
  12.                 st.push(NULL); 
  13.             }else
  14.                 // 需要額外注意下 
  15.                 st.pop(); 
  16.                 node = st.top(); 
  17.                 st.pop(); 
  18.                 res.push_back(node->val); 
  19.             } 
  20.         } 
  21.         return res; 
  22.      
  23.     } 

層次遍歷

其實,樹的遍歷也分為兩種,分別是深度優先遍歷和廣度優先遍歷。關于樹的不同深度優先遍歷(前序,中序和后序遍歷)就是遞歸和非遞歸的寫法。廣度優先遍歷在樹中,就是層次遍歷。

在二叉樹的層級遍歷中,我們需要用到隊列這個數據結構,幫助我們完成遍歷。

在Python偽代碼中,

  1. def levelOrder(root: TreeNode) -> List[List[int]]: 
  2.  # 1、判斷root 
  3.    if not root: 
  4.         return [] 
  5.     # 把root添加到quene 中 
  6.     quene = [root] 
  7.     out_list = [] 
  8.     while quene: 
  9.      # while 第一步就是求length  
  10.         length = len(queue)   
  11.         in_list = [] 
  12.         for _ in range(length): 
  13.          # 在C++中,這里需要兩行 
  14.             curnode = queue.pop(0)  # (默認移除列表最后一個元素)這里需要移除隊列最頭上的那個 
  15.             in_list.append(curnode.val) 
  16.             if curnode.left: queue.append(curnode.left
  17.             if curnode.right: queue.append(curnode.right
  18.         out_list.append(in_list) 
  19.     return out_list 

通過上面的Python偽代碼,進行書寫更高效的C++代碼。

  1. class Solution { 
  2. public
  3.     vector<vector<int>> levelOrder(TreeNode* root) { 
  4.         vector<vector<int>> res; 
  5.         queue<TreeNode*> que; 
  6.         // 判斷  root 
  7.         if (root != nullptr) que.push(root); 
  8.         while(!que.empty()) { 
  9.              // 開始先求隊列的長度 
  10.             int size = que.size(); 
  11.             vector<int> vec; 
  12.             // 迭代添加節點元素 
  13.             for (int i = 0 ; i<size; i++){ 
  14.                 TreeNode* node = que.front(); 
  15.                 que.pop(); 
  16.                 vec.push_back(node->val); 
  17.                 if (node->left) que.push(node->left); 
  18.                 if (node->right) que.push(node->right); 
  19.             } 
  20.             res.push_back(vec); 
  21.         } 
  22.         return res; 
  23.     } 
  24. }; 

上述為樹的遍歷模板。其實本質上也是深度優先遍歷與廣度優先遍歷的算法模板,許多其它操作都是建立在樹遍歷操作的基礎之上,因此掌握樹的所有遍歷方法,等于解決了一半樹的題目。

 

責任編輯:姜華 來源: Python之王
相關推薦

2021-07-13 11:32:41

二叉樹數據結構算法

2021-09-15 07:56:32

二叉樹層次遍歷

2013-07-15 16:35:55

二叉樹迭代器

2020-04-27 07:05:58

二叉樹左子樹右子樹

2021-08-06 11:34:05

二叉樹遞歸回溯

2022-10-26 23:58:02

二叉樹數組算法

2021-04-20 08:37:14

數據結構二叉樹

2021-01-13 10:03:36

二叉樹層序遍歷層次遍歷

2009-08-11 13:29:57

C#二叉樹遍歷

2023-05-08 15:57:16

二叉樹數據結構

2021-09-29 10:19:00

算法平衡二叉樹

2020-09-23 18:25:40

算法二叉樹多叉樹

2021-09-28 06:28:51

二叉樹公共祖先

2020-12-22 08:56:51

JavaScript數據結構前端

2020-11-10 09:52:16

遞歸算法代碼

2021-04-19 07:47:42

數據結構二叉樹Tree

2021-08-27 11:36:44

二叉樹回溯節點

2021-04-28 20:12:27

數據結構創建

2021-09-16 18:28:02

二叉樹遍歷遞歸

2021-03-22 08:23:29

LeetCode二叉樹節點
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲一区二区三区免费视频 | 欧美综合久久久 | 七七婷婷婷婷精品国产 | 91最新在线视频 | 日韩不卡一区二区三区 | 九九av | 日日草天天干 | 日韩精品在线一区二区 | 国产精品揄拍一区二区久久国内亚洲精 | 国产人久久人人人人爽 | 久久成人国产精品 | 精品久 | 伊人国产精品 | 国产精品日产欧美久久久久 | 久久99精品视频 | www.久久| 免费在线a视频 | 综合精品 | 色欧美综合| 成人性视频免费网站 | 龙珠z在线观看 | 亚洲成人免费视频在线观看 | 日韩成人免费视频 | 日日爱视频 | 久久久久久久一区 | 亚洲狠狠爱 | 日韩欧美国产成人一区二区 | 日韩精品中文字幕一区二区三区 | 亚洲精品4 | 欧美日韩国产三级 | 亚洲国产成人精品在线 | a级毛片国产 | 天堂中文在线播放 | 婷婷开心激情综合五月天 | 一级片在线免费看 | 精品久久久久久国产 | 黄色大片在线免费观看 | 国产免费一级一级 | 久久一区二区三区四区 | 蜜桃视频一区二区三区 | 91免费入口 |