对于非递归遍历二叉树,主要是用栈这个数据结构来模拟递归,此算法使用了command结构体标记每个节点控制是否打印,这样的好处是代码适用前中后序三种遍历方式,当标记的字符串是go时,即访问其孩子节点,若为print时打印当前结点的值,入栈顺序按前中后序不同
前序遍历
#include<string>
#include<iostream>
#include<stack>
using namespace std;
//二叉树结点结构体
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {
}
};
//控制是否打印结构体,使用它可保证此代码适用三种遍历
struct command{
string s;
TreeNode *node;
command(string s, TreeNode *node): s(s), node(node){
}
};
void preorderTraversal(TreeNode* root) {
if(root == NULL)
return;
stack<command> st;
st.push(command("go", root));
while(!st.empty()){
command com = st.top();
st.pop();
if(com.s == "print")
cout<< com.node->val<< " ";
else{
//先将右子树入栈,先访问的就是当前节点,然后左子树
if(com.node->right)
st.push(command("go", com.node->right));
if(com.node->left)
st.push(command("go", com.node->left));
st.push(command("print", com.node));
}
}
}
中序遍历
中序遍历和以上基本一样,只需要将入栈顺序变化一下即可,先将右子树入栈,再把当前节点标记改为print并入栈,最后左子树入栈
if(com.node->right)
st.push(command("go", com.node->right));
st.push(command("print", com.node));
if(com.node->left)
st.push(command("go", com.node->left));
修改顺序后,就是中序遍历了
#include<string>
#include<iostream>
#include<stack>
using namespace std;
//二叉树结点结构体
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {
}
};
//控制是否打印结构体,使用它可保证此代码适用三种遍历
struct command{
string s;
TreeNode *node;
command(string s, TreeNode *node): s(s), node(node){
}
};
void preorderTraversal(TreeNode* root) {
if(root == NULL)
return;
stack<command> st;
st.push(command("go", root));
while(!st.empty()){
command com = st.top();
st.pop();
if(com.s == "print")
cout<< com.node->val<< " ";
else{
//先将右子树入栈,再把当前节点标记改为print并入栈,最后左子树入栈
if(com.node->right)
st.push(command("go", com.node->right));
st.push(command("print", com.node));
if(com.node->left)
st.push(command("go", com.node->left));
}
}
}
中序遍历
后序遍历同样改变顺序
st.push(command("print", com.node));
if(com.node->right)
st.push(command("go", com.node->right));
if(com.node->left)
st.push(command("go", com.node->left));
修改顺序后,为后序遍历
#include<string>
#include<iostream>
#include<stack>
using namespace std;
//二叉树结点结构体
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {
}
};
//控制是否打印结构体,使用它可保证此代码适用三种遍历
struct command{
string s;
TreeNode *node;
command(string s, TreeNode *node): s(s), node(node){
}
};
void preorderTraversal(TreeNode* root) {
if(root == NULL)
return;
stack<command> st;
st.push(command("go", root));
while(!st.empty()){
command com = st.top();
st.pop();
if(com.s == "print")
cout<< com.node->val<< " ";
else{
st.push(command("print", com.node));
if(com.node->right)
st.push(command("go", com.node->right));
if(com.node->left)
st.push(command("go", com.node->left));
}
}
}