二叉树的非递归前序、中序、后序遍历小记
前序遍历:
先访问根节点,再访问左子树,再访问右子树。
该代码思路为:入栈根节点,(循环开始处)读栈顶节点,读完弹出,同时入栈该顶节点的右子树,入栈左子树,然后读栈顶节点(进入循环开始处),进入循环...
代码如下:
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> vec;
stack<TreeNode*> sta;
if(root)sta.push(root);
while(!sta.empty()){
TreeNode* tmp=sta.top();
sta.pop();
vec.push_back(tmp->val);
if(tmp->right){
sta.push(tmp->right);
}
if(tmp->left){
sta.push(tmp->left);
}
}
return vec;
}
};
中序遍历:
先访问左子树,再访问根节点,再访问右子树。
该代码思路为:只让左子节点依次入栈,首先从root开始依次循环遍历左子节点入栈。然后进入主循环依次弹出并读取栈顶节点数据,同时每次读取完判断该节点是否存在右子树,存在则让右子树为新的根节点,再次进行从root开始依次循环遍历左子节点入栈...
代码如下:
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> vec;
stack<TreeNode*> sta;
TreeNode* tmp=root;
while(tmp){//左子节点依次入栈
sta.push(tmp);
tmp=tmp->left;
}
while(!sta.empty()){
tmp=sta.top();
sta.pop();
vec.push_back(tmp->val);
tmp=tmp->right;//将右节点赋值给tmp,然后将赋值后的tmp看做一个新的二叉树的根节点,然后如下循环进行左子节点依次入栈
while(tmp){//
sta.push(tmp);
tmp=tmp->left;
}
}
return vec;
}
};
后序遍历:
先访问左子树,再访问右子树,再访问根节点。
以下代码思路参考自:https://leetcode-cn.com/problems/binary-tree-postorder-traversal/solution/a-li-mian-shi-ti-zhi-yong-zhan-qu-zuo-er-cha-shu-d/
该代码思路为:压入根节点,(循环体入口处)判断栈顶节点是否为空节点,如果为空,说明该节点的子节点已经被遍历处理完了,处理该节点;如果不为空,说明其子节点还未处理。然后压入nullptr空节点,目的是分割父节点与子节点的,然后对该父节点的右子树节点和左子树节点分别压入栈。然后回到循环体入口处,判断栈顶节点是否为空节点...
代码如下:
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> vec;
stack<TreeNode*> sta;
if(root)sta.push(root);
while(!sta.empty()){
TreeNode* tmp=sta.top();
if(nullptr==tmp){//判断该节点是否为空节点,如果为空,说明该节点的子节点已经被遍历处理完了,可以处理该父节点了
sta.pop();
vec.push_back(sta.top()->val);
sta.pop();
continue;
}
sta.push(nullptr);//这个nullptr就是用来分割父节点与子节点的
if(tmp->right){//由于是先左节点后右节点,所以是逆序压入栈
sta.push(tmp->right);
}
if(tmp->left){//left下面还有没有子节点了?不知道,所以明知不为nullptr也要回到循环体开头,让nullptr入栈,然后就可以判断left有没有叶子节点了
sta.push(tmp->left);
}
}
return vec;
}
};

浙公网安备 33010602011771号