1.前序遍历
对于任一结点P:
1)访问结点P,并将结点P入栈;
2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);
若不为空,则将P的左孩子置为当前的结点P;
3)直到P为NULL并且栈为空,则遍历结束。
//非递归先序遍历
void preOrder2(node *root){
stack<node*> stk;
node* p = root;
while (p != NULL || !stk.empty()){
while (p != NULL){
cout << p->val << " ";
stk.push(p);
p = p->left;
}
if (!stk.empty()){
p = stk.top();
stk.pop();
p = p->right;
}
}
}
3.中序遍历
对于任一结点P,
1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;
2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;
3)直到P为NULL并且栈为空则遍历结束
//非递归中序遍历
void inOrder2(node* root){
stack<node*> stk;
node* p = root;
while (p != NULL || !stk.empty()){
while (p != NULL){
stk.push(p);
p=p->left;
}
if (!stk.empty()){
p = stk.top();
stk.pop();
cout << p->val<<" ";
p = p->right;
}
}
}
3。后序遍历
后序遍历的非递归实现是三种遍历方式中最难的一种。因为在后序遍历中,要保证左孩子和右孩子都已被访问并且左孩子在右孩子前访问才能访问根结点。
对于任一结点P,将其入栈,然后沿其左子树一直往下搜索,直到搜索到没有左孩子的结点,此时该结点出现在栈顶,但是此时不能将其出栈并访问,因此其右孩子还为被访问。
所以接下来按照相同的规则对其右子树进行相同的处理,当访问完其右孩子时,该结点又出现在栈顶,此时可以将其出栈并访问。这样就保证了正确的访问顺序。
可以看出,在这个过程中,每个结点都两次出现在栈顶,只有在第二次出现在栈顶时,才能访问它。因此需要多设置一个变量标识该结点是否是第一次出现在栈顶。
void postOrder2(node* root){
stack<tmpNode*> stk;
node* p = root;
while (p != NULL || !stk.empty()){
while (p != NULL){
tmpNode *tpn = new tmpNode(p);
stk.push(tpn);
p = p->left;
}
if (!stk.empty()){
tmpNode* top = stk.top();
stk.pop();
if (top->isFirst){
top->isFirst = false;
//重新压到栈中
stk.push(top);
p = top->u->right;
}
else{
cout << top->u->val << " " ;
p=NULL;
}
}
}
}
.
完整代码
#include<iostream>
#include<string>
#include<sstream>
#include<stack>
using namespace std;
struct node{
int val;
node* left;
node* right;
node(int val) :val(val), left(NULL), right(NULL){}
};
struct tmpNode{
node* u;
bool isFirst;
tmpNode(node* u) :u(u), isFirst(true){}
};
node* builtTreeHelper(istringstream& is){
string str;
is >> str;
if (str == "#"){
return NULL;
}
node *u = new node(atoi(str.c_str()));
u->left = builtTreeHelper(is);
u->right = builtTreeHelper(is);
return u;
}
node* builtTree(string str){
istringstream is(str);
node* root = builtTreeHelper(is);
return root;
}
void preOrder(node *root){
if (root){
cout << root->val << " ";
}
if (root->left)
preOrder(root->left);
if (root->right)
preOrder(root->right);
}
//非递归先序遍历
void preOrder2(node *root){
stack<node*> stk;
node* p = root;
while (p != NULL || !stk.empty()){
while (p != NULL){
cout << p->val << " ";
stk.push(p);
p = p->left;
}
if (!stk.empty()){
p = stk.top();
stk.pop();
p = p->right;
}
}
}
//非递归中序遍历
void inOrder2(node* root){
stack<node*> stk;
node* p = root;
while (p != NULL || !stk.empty()){
while (p != NULL){
stk.push(p);
p=p->left;
}
if (!stk.empty()){
p = stk.top();
stk.pop();
cout << p->val<<" ";
p = p->right;
}
}
}
void postOrder2(node* root){
stack<tmpNode*> stk;
node* p = root;
while (p != NULL || !stk.empty()){
while (p != NULL){
tmpNode *tpn = new tmpNode(p);
stk.push(tpn);
p = p->left;
}
if (!stk.empty()){
tmpNode* top = stk.top();
stk.pop();
if (top->isFirst){
top->isFirst = false;
//重新压到栈中
stk.push(top);
p = top->u->right;
}
else{
cout << top->u->val << " " ;
}
}
}
}
int main(){
string str = "5 7 # 6 # # 3 # #";
node* root = builtTree(str);
cout << "先序遍历" << endl;
preOrder2(root);
cout << endl << "中序遍历" << endl;
inOrder2(root);
cout << endl<< "后序遍历" << endl;
postOrder2(root);
cout << endl;
return 0;
}
参考
http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html