前序和中序比较简单
使用一个if else即可判断 一直往左走就行了
但是后序比较麻烦,因为最后访问根节点,涉及到一个走过的根节点重新访问
如何知道我是第二次到达根节点访问,而不是节点左右子树还有没有访问过呢?
实际上如果这个节点是第二次到达访问,即左子树肯定已经访问过出栈,不存在了
只有可能右子树是没有访问过了,即我们用一个pre指针,指向已经访问过的上一个节点记录一下就行了,如果p->right==NULL 或 p->right==pre 说明这个点肯定需要访问,因为右子树被访问过了 或者根本没有右子树
代码如下:
#include<iostream>
#include<stack>
using namespace std;
struct TreeNode
{
TreeNode *left;
TreeNode *right;
int val;
TreeNode(int v):val(v),left(NULL),right(NULL){}
};
void preorder(TreeNode* root)
{
stack<TreeNode*> stk;
TreeNode *p = root;
TreeNode *pre = p;
while(p || !stk.empty())
{
if(p)
{
cout<<p->val<<" ";
stk.push(p);
p = p->left;
}
else
{
p = stk.top()->right;//往右走
stk.pop();
}
}
}
void inorder(TreeNode* root)
{
stack<TreeNode*> stk;
TreeNode *p = root;
TreeNode *pre = p;
while(p || !stk.empty())
{
if(p)
{
stk.push(p);
p = p->left;
}
else
{
p = stk.top();
cout<<p->val<<" "; //访问
p = p->right;
stk.pop();
}
}
}
void postorder(TreeNode* root)
{
stack<TreeNode*> stk;
TreeNode *p = root;
TreeNode *pre = p;
while(p || !stk.empty())
{
while(p) //不能用if else了
{
stk.push(p);
p = p->left;
}
p = stk.top();
if(p->right==NULL || p->right==pre)
{
cout<<p->val<<" ";
stk.pop();
pre = p;
p = NULL;
}
else
{
p = p->right;
}
}
}
int main()
{
TreeNode *root = new TreeNode(1);
root->left = new TreeNode(2);
root->right = new TreeNode(3);
/*
1
2 3
4 5
*/
TreeNode *p = root->left;
p->left = new TreeNode(4);
p->right = new TreeNode(5);
TreeNode *q = root->right;
q->left = new TreeNode(6);
q->right = new TreeNode(7);
cout<<"后序"<<endl;
postorder(root);
cout<<endl;
cout<<"前序"<<endl;
preorder(root);
cout<<endl;
cout<<"中序"<<endl;
inorder(root);
return 0;
}