二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的。对于二叉树,有前序、中序以及后序三种遍历方法。因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁。而对于树的遍历若采用非递归的方法,它们都有使用栈和不使用栈的方法,其中不使用栈的非递归遍历又是找工作面试中经常被问的问题,所以在这里做一总结:
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
一.使用栈的非递归遍历
主要思想就是利用栈来暂存下一个需要遍历的节点,然后不断退栈.
1.前序遍历
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) {
vector<int> result;
stack<TreeNode *> st;
TreeNode *tempNode;
if(root == NULL)
return result;
st.push(root);
while(!st.empty()) {
tempNode = st.top();
st.pop();
result.push_back(tempNode->val);
if(tempNode->right)
st.push(tempNode->right);
if(tempNode->left)
st.push(tempNode->left);
}
return result;
}
};
2.中序遍历
class Solution {
public:
vector<int> inorderTraversal(TreeNode *root) {
stack<TreeNode*> st;
vector<int> result;
TreeNode* temp;
if(root==NULL)
return result;
temp=root;
while(temp) {
st.push(temp);
temp=temp->left;
}
while(!st.empty()) {
temp=st.top();
result.push_back(temp->val);
st.pop();
if(temp->right) {
temp=temp->right;
while(temp) {
st.push(temp);
temp=temp->left;
}
}
}
return result;
}
};
3.后续遍历
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
TreeNode *tempNode;
stack<TreeNode*> st;
stack<int> sign;
vector<int> result;
int right;
if(root==NULL)
return result;
tempNode = root;
while(tempNode) {
st.push(tempNode);
sign.push(0);
tempNode = tempNode->left;
}
while(!st.empty()) {
tempNode = st.top();
right = sign.top();
if(tempNode->right && right==0) {
sign.pop();
sign.push(1);
tempNode = tempNode->right;
while(tempNode) {
st.push(tempNode);
sign.push(0);
tempNode = tempNode->left;
}
}
else {
st.pop();
sign.pop();
result.push_back(tempNode->val);
}
}
return result;
}
};
二.不使用栈的非递归遍历(
Morris Traversal)