递归的实现是每次递归调用都把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候就从栈顶弹出上一次递归的各项参数。可利用栈实现二叉树的前中后序遍历。
前序遍历
前序遍历是中左右的顺序,整体过程就是逐次访问父节点,压入右孩子再压入左孩子,由于访问的节点和待处理的节点顺序一致,故每次访问栈顶元素并将其存入结果集即可。
class Solution{
public:
vector<int> preorderTraversal(TreeNode* root){
vector<int> result;
stack(TreeNode*) st;
TreeNode* node = root;
//判断是否为空树
if(root == NULL) return result;
st.push(root);
while(!st.empty()){
node = st.top();
st.pop();
result.push_back(node->val);
//压入右孩子
if(node->right) st.push(node->right);
//压入左孩子
if(node->left) st.push(node->left);
}
return result;
}
};
中序遍历
对于前序遍历,要访问的元素和处理的元素都是一致的。中序遍历则是由根节点一层一层向下访问直到树的最左边的叶子节点,再开始处理节点,这造成处理顺序和访问顺序的不一致。我们可借用指针来访问节点,利用栈来处理节点上的元素。
整体过程是从根节点逐次访问到最左边的叶子节点,并在栈中保存访问的节点路径,然后取栈顶元素将其存入到结果集中,并转向栈顶元素的右子树中。在右子树中仍然进行相同的操作。
class Solution{
public:
vector<int> inorderTraversal(TreeNode* root){
vector<int> result;
stack(TreeNode*) st;
//判断是否为空树
if(root == NULL) return result;
TreeNode* cur = root;
while(cur != NULL || !st.empty()){
//栈用以记录访问路径,记录最左边的路径
if(cur!=NULL){
st.push(cur);
cur=cur->left;
}else{
// 逐次回退并记录节点元素值,若存在右子树则进入右子树:再执行同样的访问路径记录以及元素值记录和回退。
cur = st.top();
st.pop();
result.push_back(cur->val);
cur = cur->right;
}
return result;
}
};
后序遍历
后序遍历可以仿照前序遍历去写,前序遍历是中左右,只需要按照中右左去遍历树然后逆序输出遍历结果即可得到左右中的后序遍历结果。
class Solution{
public:
vector<int> postorderTraversal(TreeNode* root){
vector<int> result;
stack(TreeNode*) st;
//判断是否为空树
if(root == NULL) return result;
st.push(root);
//中右左遍历树
while(!st.empty()){
TreeNode* node = st.top();
st.pop();
result.push_back(node->val);
//压入左孩子
if(node->left) st.push(node->left);
//压入右孩子
if(node->right) st.push(node->right);
}
reverse(result.begin(),result.end());
return result;
}
};
标签:node,遍历,cur,迭代,st,result,root,二叉树
From: https://www.cnblogs.com/perngfey-note/p/18118442