递归的前序、中序、后序遍历与概念基本一致,简单明了。而非递归遍历稍微麻烦,确实最容易被问到的东西。
首先看非递归前序遍历:用栈实现,先访问根节点,然后压入右子树,再压入左子树。
Binary Tree Preorder Traversal
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) {
vector<int> ret;
stack<TreeNode*> s;
if(root!=NULL){
s.push(root);
while(!s.empty()){
root=s.top();
s.pop();
ret.push_back(root->val);
if(root->right!=NULL){
s.push(root->right);
}
if(root->left!=NULL){
s.push(root->left);
}
}
}
return ret;
}
};
中序遍历非递归实现:将左子树一直压栈,直到左子树为空,然后取栈顶元素,访问栈顶元素,并访问其右子树。
Binary Tree Inorder Traversal
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode *root) {
vector<int> ret;
stack<TreeNode*> s;
TreeNode *pRoot=root;
while(pRoot!=NULL||!s.empty()){
while(pRoot!=NULL){
s.push(pRoot);
pRoot=pRoot->left;
}
if(!s.empty()){
pRoot=s.top();
ret.push_back(pRoot->val);
s.pop();
pRoot=pRoot->right;
}
}
return ret;
}
};
后序非递归遍历:
这里参考了一个网上的容易理解的方法:对于任一节点,将其入栈,如果该节点没有左子树和右子树或者其左孩子和右孩子已经被访问过,则可访问该节点。否则,将该节点的右子树压栈,将该节点的左子树压栈。
Binary Tree Postorder Traversal
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> result;
stack<TreeNode*> s;
TreeNode *cur=NULL,*pre=NULL;
if(root==NULL){
return result;
}
s.push(root);
while(!s.empty()){
cur=s.top();
if((cur->left==NULL&&cur->right==NULL)||(pre!=NULL&&cur->left==pre)||(pre!=NULL&&cur->right==pre)){
result.push_back(cur->val);
s.pop();
pre=cur;
}
else{
if(cur->right!=NULL){
s.push(cur->right);
}
if(cur->left!=NULL){
s.push(cur->left);
}
}
}
return result;
}
};