1.非递归的遍历其实就是使用栈来模拟递归的遍历。
2.三个遍历中(非递归),前序和中序类似,只是访问根结点的时机不同:前序是入栈时访问根结点,而中序是出栈是访问根结点。
3.后序遍历是不同的:它需要有个标记来记录之前访问过的右结点,让结点不再访问已经访问过的右结点,否则会死循环。
1.前序遍历:
1.递归:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void _preorderTraversal(TreeNode* root,vector<int>& v){
if(root==nullptr)
return;
v.push_back(root->val);
_preorderTraversal(root->left,v);
_preorderTraversal(root->right,v);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> v;
_preorderTraversal(root,v);
return v;
}
};
2.非递归:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> v;
stack<TreeNode*> st;
TreeNode* cur=root;
while(cur || !st.empty()){ //当根不为空或栈不空
//先访问树的左路结点
//再访问树的右路结点
while(cur){
v.push_back(cur->val); //访问根结点
st.push(cur); //入栈
cur=cur->left;
}
//取栈中左路结点的右子树出来访问
cur=st.top(); //返回根结点
st.pop(); //出栈
cur=cur->right; //迭代访问右子树
}
return v;
}
};
2.中序遍历:
1.递归:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void _inorderTraversal(TreeNode* root,vector<int>& v){
if(root==nullptr)
return;
_inorderTraversal(root->left,v);
v.push_back(root->val);
_inorderTraversal(root->right,v);
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> v;
_inorderTraversal(root,v);
return v;
}
};
2.非递归:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> v;
stack<TreeNode*> st;
TreeNode* cur=root;
while(cur || !st.empty()){
//先访问树的左路结点
//再访问左路结点的右子树
while(cur){
st.push(cur);
cur=cur->left;
}
cur=st.top(); //返回根结点
st.pop(); //出栈
v.push_back(cur->val); //访问根结点
//取栈中左路结点的右子树来访问
cur=cur->right;
}
return v;
}
};
3.后序遍历:
1.递归:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void _postorderTraversal(TreeNode* root,vector<int>& v){
if(root==nullptr)
return;
_postorderTraversal(root->left,v);
_postorderTraversal(root->right,v);
v.push_back(root->val);
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> v;
_postorderTraversal(root,v);
return v;
}
};
2.非递归:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> v;
stack<TreeNode*> st;
TreeNode* cur=root;
TreeNode* last=nullptr; //记录最近访问的结点
while(cur || !st.empty()){
//左路结点入栈
while(cur){
st.push(cur);
cur=cur->left;
}
//取左路结点为当前结点
//如果当前结点的右子树为空 或者 当前结点的右子树已经被访问过了(即last为当前结点的右孩子时),则可以访问当前结点了
//否则迭代访问当前结点的右子树
cur=st.top();
if(cur->right==nullptr || last==cur->right){
v.push_back(cur->val); //访问
st.pop(); //出栈
last=cur; //记录最近访问的结点
cur=nullptr; //置空
}
else
cur=cur->right;
}
return v;
}
};