前序遍歷:先訪問該節點,然后訪問該節點的左子樹和右子樹;
中序遍歷:先訪問該節點的左子樹,然后訪問該節點,再訪問該節點的右子樹;
后序遍歷:想訪問該節點的左子樹和右子樹,然后訪問該節點。
遞歸遍歷
?
對于遞歸遍歷比較簡單:
?
void preorder(TreeNode* root) {
????if (root == NULL)
????????return;
????visit(root);
????preorder(root->left);
????preorder(root->right);
}
?
void inorder(TreeNode* root) {
????if (root == NULL)
????????return;
????inorder(root->left);
????visit(root);
????inorder(root-
?
void postorder(TreeNode* root) {
????if (root == NULL)
????????return;
????postorder(root->left);
????postorder(root->right);
????visit(root);
}
非遞歸(迭代)遍歷
?
非遞歸實現在遍歷根節點后還要回來,因此要基于棧(先進后出)來保存節點。
注:二叉樹遍歷的非遞歸實現文章里有不同的實現方式,更易于理解記憶。
?
前序遍歷
?
壓入順序:右子樹->左子樹->根節點
使得訪問的時候的順序成為:根->左子樹->右子樹
?
????vector
????????vector
????????stack
????????if (root == NULL)
????????????return result;
????????s.push(root);
????????while(!s.empty()) {
????????????TreeNode* p = s.top();
????????????s.pop();
????????????result.push_back(p->val);
????????????if (p->right)
????????????????s.push(p->right);
????????????if (p->left)
????????????????s.push(p->left);
????????}
????????return result;
????}
中序遍歷
?
壓入順序:右子樹->根->左子樹
只有當左子樹已經訪問完后,才能訪問根節點
?
對于任一結點P,
1)若其左孩子不為空,則將P入棧并將P的左孩子置為當前的P,然后對當前結點P再進行相同的處理;
2)若其左孩子為空,則取棧頂元素并進行出棧操作,訪問該棧頂結點,然后將當前的P置為棧頂結點的右孩子;
3)直到P為NULL并且棧為空則遍歷結束
vector
????????vector
????????stack
????????if (root == NULL)
????????????return result;
????????TreeNode* p = root;
????????while (!s.empty() || p != NULL) {
????????????if (p != NULL) {
????????????????// push 左子樹入棧
????????????????s.push(p);
????????????????p = p->left;
????????????} else {
????????????????// 左子樹為空時,訪問該節點,然后訪問右子樹
????????????????p = s.top();
????????????????result.push_back(p->val);
????????????????s.pop();
????????????????p = p->right;
????????????}
????????}
????????return result; ?
????}
后序遍歷
先壓入根,然后是右子樹,最后左子樹
要求最后訪問根節點,即訪問該根節點時必須訪問完左子樹和右子樹,我們只需要保證訪問某一節點時,該節點的右子樹已經被訪問,否則需要將該節點重新壓入棧。
?
對于任一結點P,將其入棧,然后沿其左子樹一直往下搜索,直到搜索到沒有左孩子的結點,此時該結點出現在棧頂,但是此時不能將其出棧并訪問,因此其右孩子還為被訪問。所以接下來按照相同的規則對其右子樹進行相同的處理,當訪問完其右孩子時,該結點又出現在棧頂,此時可以將其出棧并訪問。這樣就保證了正確的訪問順序。可以看出,在這個過程中,每個結點都兩次出現在棧頂,只有在第二次出現在棧頂時,才能訪問它。
??vector
????????vector
????????if (root == NULL)
????????????return result;
????????stack
????????TreeNode* p = root; ?//當前正訪問的節點
????????TreeNode* q; ?//記錄剛剛訪問過的節點
????????do{
????????????while (p != NULL) {
????????????????s.push(p);
????????????????p = p->left;
????????????}
????????????q = NULL;
????????????while (!s.empty()) {
????????????????p = s.top();
????????????????s.pop();
????????????????if (p->right == q) { ?//當右子樹已經訪問過了,才可以訪問根
????????????????????result.push_back(p->val);
????????????????????q = p; ?//記錄剛剛訪問過的節點
????????????????} else {
????????????????????s.push(p); //第一次訪問到該節點,需要將它重新入棧
????????????????????p = p->right;
????????????????????break;
????????????????}
?
????????????}
????????} while (!s.empty());
????????return result;
????}
二叉樹的前序遍歷、中序遍歷、后續遍歷的非遞歸實現
- C語言(117708)
- 二叉樹(12147)
相關推薦
文件系統-多叉樹與二叉樹的轉化
在這一節中,我們來學習如何使用程序來實現一棵文件樹。在上一節中,我們了解到使用文件樹的方式來整合計算機中所有的資源,而這一棵文件樹則是一棵多叉樹。也就是說,樹上的每一個節點都可能有多個子節點。
2023-10-11 10:06:2877
數據結構面試之二叉樹相關操作
根據前序可知根結點為1;
根據中序可知 4 7 2 為根結點 1 的左子樹和 8 5 9 3 6 為根結點 1 的右子樹;
遞歸實現,把 4 7 2 當做新的一棵樹和 8 5 9 3 6 也當做新的一棵樹;
在遞歸的過程中輸出后序。
2023-10-10 14:50:4640
如何遍歷中文字符串
今天和大家分享下如何遍歷中文字符串,主要是如何打印中文字符,因為中文字符串每個字符占用不只一個字節的空間,如果我們逐個字節遍歷,會出現奇怪的結果。而UTF-8編碼寫的中文字符是有特定結構的,我們可以
2023-07-03 09:15:26185
解析LeetCode第226號題目:反轉二叉樹
*簡單講就是把每個節點的左子樹和右子樹進行交換** 。
顯然,這需要我們能夠遍歷該二叉樹。
那么遍歷二叉樹就有兩種經典的解法:深度優先遍歷,Deep First Search,簡稱DFS;另一個是廣度優先遍歷,Breadth First Search,簡稱BFS。
2023-02-17 14:52:30405
HashMap遍歷操作為什么不能一邊遍歷一遍刪除呢?
上面出現這樣的原因是在使用 foreach 對 HashMap 進行遍歷時,同時進行 put 賦值操作會有問題,異常 ConcurrentModificationException。
2023-02-10 11:25:53233
五張圖帶你體會堆算法
二叉堆是一種特殊的堆,二叉堆是完全二叉樹或者近似完全二叉樹,二叉堆滿足堆特性:父節點的鍵值總是保持固定的序關系于任何一個子節點的鍵值,且每個節點的左子樹和右子樹都是一個二叉堆。
2022-11-10 09:29:07359
二叉樹的統一迭代法
我們以中序遍歷為例,在二叉樹:聽說遞歸能做的,棧也能做!中提到說使用棧的話,無法同時解決訪問節點(遍歷節點)和處理節點(將元素放進結果集)不一致的情況。
2022-08-03 11:22:59244
用迭代法編寫二叉樹的前后中序遍歷案例
遞歸的實現就是:每一次遞歸調用都會把函數的局部變量、參數值和返回地址等壓入調用棧中,然后遞歸返回的時候,從棧頂彈出上一次遞歸的各項參數,所以這就是遞歸為什么可以返回上一層位置的原因。
2022-07-25 15:40:19266
為什么可以用迭代法來實現二叉樹的前后中序遍歷呢
我們在棧與隊列:匹配問題都是棧的強項中提到了,遞歸的實現就是:每一次遞歸調用都會把函數的局部變量、參數值和返回地址等壓入調用棧中,然后遞歸返回的時候,從棧頂彈出上一次遞歸的各項參數,所以這就是遞歸為什么可以返回上一層位置的原因。
2022-07-19 11:50:17710
怎么就能構造成二叉樹呢?
一直跟著公眾號學算法的錄友 應該知道,我在二叉樹:構造二叉樹登場!,已經講過,只有 中序與后序 和 中序和前序 可以確定一顆唯一的二叉樹。前序和后序是不能確定唯一的二叉樹的。
2022-07-14 11:20:47754
判斷對稱二叉樹要比較的是哪兩個節點
對于二叉樹是否對稱,要比較的是根節點的左子樹與右子樹是不是相互翻轉的,理解這一點就知道了其實我們要比較的是兩個樹(這兩個樹是根節點的左右子樹),所以在遞歸遍歷的過程中,也是要同時遍歷兩棵樹。
2022-07-06 16:26:05637
C語言數據結構:什么是二叉樹?
完全二叉樹:完全二叉樹是效率很高的數據結構。對于深度為K,有n個節點的二叉樹,當且僅當每一個節點都與深度為K的滿二叉樹中編號從1至n的節點一一對應時,稱為完全二叉樹。
2022-04-21 16:20:101349
二叉樹上應該怎么求
? 二叉樹上應該怎么求,二叉搜索樹上又應該怎么求? 在求眾數集合的時候有一個技巧,因為題目中眾數是可以有多個的,所以一般的方法需要遍歷兩遍才能求出眾數的集合。 但可以遍歷一遍就可以求眾數集合,使用了
2021-11-22 11:32:461063
二叉排序樹AVL如何實現動態平衡
? 什么是AVL樹 大家好,我是bigsai,好久不見,甚是想念,今天給大家講講AVL樹。 對于樹這種數據結構,想必大家也已經不再陌生,我們簡單回顧一下。 在樹的種類中,通常分成二叉樹和多叉樹,我們
2021-10-28 17:02:261246
算法學習中如何打印二叉樹節點
大家好,我是吳師兄,直接開始今天的算法學習,沖沖沖。 一、題目描述 從上到下打印出二叉樹的每個節點,同一層的節點按照從左到右的順序打印。 例如: 給定二叉樹:? [3,9,20,null,null
2021-10-22 09:37:001231
如何修剪二叉搜索樹
的值在[L, R]中 (R=L) 。你可能需要改變樹的根節點,所以結果應當返回修剪好的二叉搜索樹的新的根節點。 ?? 思路 相信看到這道題目大家都感覺是一道簡單題(事實上leetcode上也標明是簡單)。 但還真的不簡單! 遞歸法 直接想法就是:遞歸處理,然后遇
2021-10-11 14:16:201042
C++基礎語法中的二叉樹詳解
本期是C++基礎語法分享的第十四節,今天給大家來梳理一下樹! ? 二叉樹 BinaryTree.cpp: #include 《stdio.h》#include 《stdlib.h》 #define
2021-09-29 18:02:521662
如何才能夠翻轉二叉樹
有所收獲! 226.翻轉二叉樹題目地址:https://leetcode-cn.com/problems/invert-binary-tree/ 翻轉一棵二叉樹。 這道題目背后有一個讓程序員心酸的故事
2021-09-01 11:45:311390
C語言編程中如何求出二叉樹后序遍歷
題目 已知二叉樹前序為 ABDFGCEH 后序序列為 BFDGACEH ,要求輸出后序遍歷為 FGDBHECA 大體思路 又先序得出根,先序的根后為左樹一部分,我們再在中序序列里找到先序的根,此處
2021-08-23 11:04:523299
二叉樹的所有路徑介紹
以為只用了遞歸,其實還用了回溯 257. 二叉樹的所有路徑 題目地址:https://leetcode-cn.com/problems/binary-tree-paths/ 給定一個二叉樹,返回所有
2021-08-13 17:51:512403
二叉樹的前序遍歷非遞歸實現
我們之前說了二叉樹基礎及二叉的幾種遍歷方式及練習題,今天我們來看一下二叉樹的前序遍歷非遞歸實現。 前序遍歷的順序是, 對于樹中的某節點,先遍歷該節點,然后再遍歷其左子樹,最后遍歷其右子樹。 我們先來
2021-05-28 13:59:071420
二叉樹操作的相關知識和代碼詳解
見的二叉樹操作作個總結: 前序遍歷,中序遍歷,后序遍歷; 層次遍歷; 求樹的結點數; 求樹的葉子數; 求樹的深度; 求二叉樹第k層的結點個數; 判斷兩棵二叉樹是否結構相同; 求二叉樹的鏡像; 求兩個結點的最低公共祖先結點; 求任
2020-12-12 11:04:441564
螺旋遍歷二維數組漫畫講解
來自公眾號:程序員小灰 第二天 什么意思呢?我們來舉個例子,給定下面這樣一個二維數組: 我們需要從左上角的元素1開始,按照順時針進行螺旋遍歷,一直遍歷完所有的元素,遍歷的路徑就像下圖一樣: 經過這樣
2020-11-26 14:01:421384
Offer系列面試題0:重建二叉樹
以本題的序列為例,前序遍歷序列的第一個數字 3 就是根結點的值,在中序遍歷序列,找到根結點值的位置。根據中序遍歷特點,在根結點的值 3 前面的數字都是左子樹結點的值,在根結點的值 3 后面的數字都是右子樹結點的值。
2020-07-09 15:03:541224
紅黑樹(Red Black Tree)是一種自平衡的二叉搜索樹
平衡(Balance):就是當結點數量固定時,左右子樹的高度越接近,這棵二叉樹越平衡(高度越低)。而最理想的平衡就是完全二叉樹/滿二叉樹,高度最小的二叉樹。
2020-07-01 15:05:404117
刪除二叉搜索樹中的節點
因為是二叉搜索樹,對于樹上每個節點來說,其 右子樹的節點都要大于其左子樹的節點 ,那么要找對應節點,我們可以從根節點開始,一路比較,大的話就去右邊找,小的話就去左邊找,這樣每次我們都往下,可以保證時間復雜度是 O(h)。
2020-06-23 10:33:522701
面試二叉樹看這11個就夠了
根據前、中序遍歷的特點,(根左右、左根右),先根據前序遍歷確定根節點,然后在中序遍歷知道該根節點的左右樹的數量,反推出前序遍歷中左子樹的結點有哪些。根據該思路進行遞歸即可完成二叉樹的重建。
2019-11-27 16:25:063044
面試算法之重建二叉樹
節點呢?左子節點有幾個呢?很顯然我們是不知道的,由此可以得出,只知道前序遍歷是不可能反推出二叉樹的,中序遍歷也是如此,自己可以嘗試一下。
2019-11-27 15:59:392203
詳解電源二叉樹到底是什么
作為數據結構的基礎,樹分很多種,像 AVL 樹、紅黑樹、二叉搜索樹....今天我想分享的是關于二叉樹,一種基礎的數據結構類型。今天從實例入手,給大家介紹一個電源二叉樹的分析。
2019-06-06 15:05:468782
二叉樹,一種基礎的數據結構類型
然后我們再定義一棵深度也為 3 的二叉樹,該二叉樹的 n 個結點(n≤7),當從 1 到 n 的每個結點都與上圖中的編號結點一一對應時,這二叉樹就稱為完全二叉樹。
2019-04-13 10:48:263780
基于二叉樹的ensemble異常檢測算法
次數即為從決策樹的根節點到葉子節點所經歷的邊數,稱之為路徑長度(path length)。假設樣本集合共有n個樣本點,對于二叉查找樹(Binary Search Tree, BST),則查找失敗的平均路徑長度為
2018-12-11 16:57:513610
計算機二級公共基礎知識完整版免費下載快來復習吧!
經過對部分考生的調查以及對近年真題的總結分析,筆試部分經常考查的是算法復雜度、數據結構的概念、棧、二叉樹的遍歷、二分法查找,讀者應對此部分進行重點學習。詳細重點學習知識點
2018-09-28 15:30:2412
RFID防碰撞策略
協議內嵌入其中,解決了傳統RFID系統標簽識別效率較低、成本過高的問題,同時具有較高的安全性優勢。與后退二叉樹、動態自適應、二叉樹搜索等算法進行比較,結果表明該策略能大大降低系統搜索的次數,提高標簽的吞吐率。
2018-02-05 15:53:251
熵的二叉樹多類支持向量機的漏洞分類
為了有效提高漏洞分類的準確性,針對基于二叉樹多類支持向量機分類算法的分類復雜性和分類結果依賴二叉樹的結構等缺點,提出了一種基于熵的二又樹多類支持向量機的漏洞分類算法。根據定義最小超球體進行漏洞
2018-01-25 10:40:380
AVL 樹和普通的二叉查找樹的詳細區別分析
那 AVL 樹和普通的二叉查找樹有何區別呢?如圖,如果我們插入的是一組有序上升或下降的數據,則一棵普通的二叉查找樹必然會退化成一個單鏈表,其查找效率就降為 O(n)。而 AVL 樹因其平衡的限制,可以始終保持 O(logn) 的時間復雜度。
2018-01-15 14:36:115199
基于二叉樹的算術編碼二值化方法
在算術編碼研究中,待編碼的語法元素需要采用何種二值化方法以及二值化后每個比特的概率模型選擇是算術編碼算法設計必須面對的問題.提出了一種基于二叉樹的熵編碼二值化方法.該方法首先獲得語法元素的統計概率
2018-01-03 16:53:170
廣度優先遍歷的關鍵路線生成樹算法
關鍵路線的確定對于運用關鍵路線法進行項目管理具有十分重要的意義。本文首先定義了項目管理圖模型,然后在此基礎上提出了一種基于廣度優先遍歷的關鍵路線生成樹算法,最后通過對項目管理圖模型的研究,實現了
2017-12-19 11:28:380
哈夫曼樹基本概念與構造
哈夫曼樹又稱最優二叉樹。它是 n 個帶權葉子結點構成的所有二叉樹中,帶權路徑長度 WPL 最小的二叉樹。若在一棵樹中存在著一個結點序列 k1,k2,……,kj, 使得 ki是ki+1 的雙親(1《=i《j),則稱此結點序列是從 k1 到 kj 的路徑。
2017-12-11 10:01:1233480
二叉樹層次遍歷算法的驗證
實現二叉樹的層次遍歷算法,并對用”A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))”創建的二叉樹進行測試。
2017-11-28 01:05:461723
如何使用遞歸遍歷轉換樹形數據
廣度遍歷的過程是把所有節點扁平化到一個隊列中了,這個過程是不可逆 的,換句話說,我們在處理過程中丟掉了樹形結構信息。然后我們要生成的 DOM 樹,是需要結構信息的——因此,需要將結構信息附加在每個節點上。這里我們把生成的 DOM 和數據節點綁定起來,由 DOM 保存結構信息。
2017-11-02 16:46:304277
java 二叉樹實現
父子關系的節點的有限集合。對于這個有限的節點集合而言,它滿足如下條件: 當N=0時,改節點集合為空,這課樹也被稱為空樹 在任意的非空樹中,有且僅有一個根(root)節點 當N》1時,除根節點以外的其余節點可分為M個互為相交的有限集合T1,
2017-09-28 14:48:162
遍歷圖像像素的14種方法_OpenCV2版書本配套示例程序24
遍歷圖像像素的14種方法_OpenCV2版書本配套示例程序24,來自一本國外OpenCV2書籍的示例-遍歷圖像像素的14種方法。
2016-06-06 15:20:546
二叉樹法遍歷查找代碼
2015-10-12 18:10:314
先序創建一顆二叉樹遍歷
2014-03-17 18:27:0813
基于二叉樹的時序電路測試序列設計
為了實現時序電路狀態驗證和故障檢測,需要事先設計一個輸入測試序列。基于二叉樹節點和樹枝的特性,建立時序電路狀態二叉樹,按照電路二叉樹節點(狀態)與樹枝(輸入)的層次邏輯
2012-07-12 13:57:4034
華為部分面試題
第二部分,填空題 1. 什么是UML?分哪兩類? 2. OS一般的兩種進程調度策略 3. 進程間的四種通訊方式 4. 一棵二叉樹的前序,中序,后序遍歷結果
2011-09-07 16:14:17138
Merkle樹遍歷技術的研究
Merkle樹應用于數字加密技術。它的遍歷技術主要包含樹的根節點生成和認證路徑的生成。本文主要比較各種Merkle樹的遍歷技術,提出自己的遍歷方法,并進行了實驗仿真和對實驗結果的
2010-03-01 16:16:0214
基于Hash和二叉樹的路由表查找算法
基于Hash和二叉樹的路由表查找算法
:提出了一種基于Hash和二又樹的路由表查找算法,這一算法可以滿足()C-768的轉發要求,支持超過10萬條前綴的大規模路由表,并且
2010-02-22 17:06:1535
基于二叉樹分解的自適應防碰撞算法
該文提出了一種基于二叉樹分解的自適應防碰撞算法。新算法利用標簽EPC 的唯一性,通過時隙分配估計標簽的分布情況,對發生碰撞的時隙進行二叉樹搜索,從而將一個龐大且復雜
2009-11-17 14:09:2821
基于三角形二叉樹的實時大規模地形渲染算法
提出一種大規模地形渲染算法,對大規模地形進行分塊,用三角形二叉樹表示地形網格,在實時漫游中,通過強制分割和強制合并實時更新網格,充分利用幀與幀之間的連貫性并自
2009-04-01 09:20:2517
二叉樹算法在單總線技術中的應用
介紹了單總線技術和二叉樹算法。單總線技術可以將地址線、數據線和控制線合成一根線,并允許在這根線上掛接多個單總線器件。提出了用二叉樹算法搜索單總線器件注冊碼,并
2009-03-16 09:38:1220
評論
查看更多