leetcode | 二叉樹的前序遍歷、中序遍歷、後續遍歷的非遞迴實現
- 前序遍歷:先訪問該節點,然後訪問該節點的左子樹和右子樹;
- 中序遍歷:先訪問該節點的左子樹,然後訪問該節點,再訪問該節點的右子樹;
- 後序遍歷:想訪問該節點的左子樹和右子樹,然後訪問該節點。
遞迴遍歷
對於遞迴遍歷比較簡單:
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-<right);
}
void postorder(TreeNode* root) {
if (root == NULL)
return;
postorder(root->left);
postorder(root->right);
visit(root);
}
非遞迴(迭代)遍歷
非遞迴實現在遍歷根節點後還要回來,因此要基於棧(先進後出)來儲存節點。
注
前序遍歷
壓入順序:右子樹->左子樹->根節點
使得訪問的時候的順序成為:根->左子樹->右子樹
vector<int> preorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> s;
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<int> inorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> s;
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<int> postorderTraversal(TreeNode* root) {
vector<int> result;
if (root == NULL)
return result;
stack<TreeNode*> s;
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;
}
相關推薦
二叉樹 給定一個節點,求中序遍歷下一個節點
題目描述 給定一個二叉樹和其中的一個結點,請找出中序遍歷順序的下一個結點並且返回。注意,樹中的結點不僅包含左右子結點,同時包含指向父結點的指標。 using namespace std; /
PTA 5-11 玩轉二叉樹 (25分)【已知中序和前序求樹】
5-11 玩轉二叉樹 (25分) 給定一棵二叉樹的中序遍歷和前序遍歷,請你先將樹做個鏡面反轉,再輸出反轉後的層序遍歷的序列。所謂鏡面反轉,是指將所有非葉結點的左右孩子對換。這裡假設鍵值都是互
[Leetcode 144]二叉樹前序遍歷Binary Tree Preorder Traversal
public list left 前序 output nod roo strong while 【題目】 Given a binary tree, return the preordertraversal of its nodes‘ values. Example: Inp
Leetcode:二叉樹的前序遍歷
Leetcode: 二叉樹的前序遍歷 最近在複習資料結構, 感覺很多東西都忘得的差不多了,哪怕是看完書再看視訊,還是容易忘,所以乾脆想著配合leetcode來刷吧,Python實現起來很簡單,但是C語言也不能丟,所以C語言和Python一起吧。 題目: 給定一個二叉樹,返回它的前序遍歷。 輸入: [
[每日leetcode]二叉樹的前序、中序、後序遍歷
二叉樹的前序遍歷 給定一個二叉樹,返回它的 前序 遍歷。 示例: 輸入: [1,null,2,3] 1 \ 2 / 3 輸出: [1,2,3] 進階: 遞迴演算法很
【LeetCode】Binary Tree Preorder Traversal 二叉樹前序遍歷遞迴以及非遞迴演算法
Total Accepted: 17403 Total Submissions: 50093 My Submissions Given a binary tree, return the preorder traversal of its nodes' values.
leetcode | 二叉樹的前序遍歷、中序遍歷、後續遍歷的非遞迴實現
前序遍歷:先訪問該節點,然後訪問該節點的左子樹和右子樹; 中序遍歷:先訪問該節點的左子樹,然後訪問該節點,再訪問該節點的右子樹; 後序遍歷:想訪問該節點的左子樹和右子樹,然後訪問該節點。 遞迴遍歷 對於遞迴遍歷比較簡單: void preo
LeetCode 二叉樹的前序遍歷 java
給定一個二叉樹,返回它的 前序 遍歷。 示例:輸入: [1,null,2,3] 1 \ 2 / 3 輸出: [1,2,3]/** * Definition for a binary tree node. * public cl
Leetcode:二叉樹的層序遍歷、前中後序遍歷非遞迴版
102. 二叉樹的層次遍歷 給定一個二叉樹,返回其按層次遍歷的節點值。 (即逐層地,從左到右訪問所有節點)。 例如: 給定二叉樹: [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回
LeetCode 144 Binary Tree Preorder Traversal(二叉樹前序遍歷)
Given a binary tree, return thepreordertraversal of its nodes' values. For example: Given binary tr
leetcode 二叉樹的前序中序後序遍歷
給定一個二叉樹 示例:輸入: [1,null,2,3] 1 \ 2 / 3 輸出: [1,2,3] 前序遍歷#include <stdio.h>
二叉樹前序、中序遍歷得到後序遍歷
() level struct OS spa str sel src [] 二叉樹的前序遍歷為:{1,2,4,7,3,5,6,8},中序遍歷為:{4,7,2,1,5,3,8,6},求後序遍歷 # -*- coding:utf-8 -*- class Nod
數據結構35:二叉樹前序遍歷、中序遍歷和後序遍歷
tdi 代碼 nod 完成 循環 同時 reat pan 設置 遞歸算法底層的實現使用的是棧存儲結構,所以可以直接使用棧寫出相應的非遞歸算法。 先序遍歷的非遞歸算法 從樹的根結點出發,遍歷左孩子的同時,先將每個結點的右孩子壓棧。當遇到結點沒有左孩子的時候,取棧頂的右
golang二叉樹前序,中序,後序非遞歸遍歷算法
rec == int post order nta rev UC right package main import ( "container/list" "fmt" ) // Binary Tree type Bin
二叉樹前序、中序、後序(遞迴 / 非遞迴)遍歷
前語 二叉樹的遍歷是指按一定次序訪問二叉樹中的每一個結點,且每個節點僅被訪問一次。 前序遍歷 若二叉樹非空,則進行以下次序的遍歷: 根節點—>根節點的左子樹—>根節點的右子樹 若要遍歷左子樹和右子樹,仍然需要按照以上次序進行,所以前序遍歷也是一個遞
【演算法】二叉樹前序、中序、後序遍歷相互求法(轉)
二叉樹前序、中序、後序遍歷相互求法 原文地址 今天來總結下二叉樹前序、中序、後序遍歷相互求法,即如果知道兩個的遍歷,如何求第三種遍歷方法,比較笨的方法是畫出來二叉樹,然後根據各種遍歷不同的特性來求,也可以程式設計求出,下面我們分別說明。  
pat 甲級 1099(二叉樹前序+層序遍歷)
題目連結:https://pintia.cn/problem-sets/994805342720868352/problems/994805367987355648 思路: (1)建立二叉樹 (2)將b陣列排序得到二叉樹的前序遍歷 (3)層序遍歷二叉樹 注意:二叉樹前序遍歷是先判
leetcode144 二叉樹前序遍歷與中序遍歷的不同
二叉樹中序遍歷 class Solution { public: vector<int> inorderTraversal(TreeNode* root) { TreeNode* cur=root; vector<int>
二叉樹的前序,中序,後序遍歷。用遞迴和非遞迴實現
#include<iostream> #include<stack> using namespace std; #define MAX 100 typedef struct Tree{ int data; Tree*lchild; Tree*rchild; }
已知中序、後序構造二叉樹(關鍵詞:二叉樹/前序/先序/中序/後序/先根/中根/後根/遍歷/搜尋/查詢)
已知中序、後序構造二叉樹 遞迴演算法 def buildTree(inorder, postorder): if inorder and postorder: postRootVal = postorder