//非递归后序遍历: //------------------------------------------------------------------------- //(不会破坏树) // 有左儿子进,无左二子调用右儿子 // 无左右儿子或左右儿子均被访问过了,出栈并输出 //-------------------------------------------------------------------------- // 使用栈(不会破坏树) // 右儿子先进栈道,再左儿子进 // 儿子进栈后,使用顶点元素, a.元素无子或有子但是已被访问过了,出栈道,标记该元素 // b.有子and未被访问过的 //栈道空了->ok //--------------------------------------------------------------------------- // 使用栈(会破坏树) // 右儿子先进栈道,再左儿子进 // 儿子进栈后,使用顶点元素, a.元素无子,出栈道,设置父的一个子为NULL; // b.有子,进栈道 //栈道空了->ok //---------------------------------------------------------------------------- #include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <iostream.h> #define MaxSize 100 #define max 100 typedef char ElemType; typedef struct node { ElemType data; //数据元素 struct node *lchild; //指向左孩子 struct node *rchild; //指向右孩子 } BTNode; void CreateBTNode(BTNode *&b,char *str); void houxu(BTNode* head); //后序 void houxu1(BTNode* head); //后序 void houxu2(BTNode* head);//后序 void main() { BTNode *b; //CreateBTNode(b,"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))"); CreateBTNode(b,"A(B(C(D,),E(F,G)),I(,J))"); //houxu(b);cout<<endl; houxu1(b);cout<<endl; houxu2(b);cout<<"\n"; } void CreateBTNode(BTNode *&b,char *str) ///////////////////////////////////////////////////由str串创建二叉链 { BTNode *St[MaxSize],*p=NULL; int top=-1,k,j=0; char ch; b=NULL; //建立的二叉树初始时为空 ch=str[j]; while (ch!=‘\0‘) //str未扫描完时循环 { switch(ch) { case ‘(‘:top++;St[top]=p;k=1; break; //为左节点 case ‘)‘:top--;break; case ‘,‘:k=2; break; //为右节点 default:p=(BTNode *)malloc(sizeof(BTNode)); p->data=ch;p->lchild=p->rchild=NULL; if (b==NULL) //p指向二叉树的根节点 b=p; else //已建立二叉树根节点 { switch(k) { case 1:St[top]->lchild=p;break; case 2:St[top]->rchild=p;break; } } } j++; ch=str[j]; } } //---------------------------------------------------------------------------------------// //void houxu(BTNode* head) // 连接地址 http://blog.csdn.net/h1023417614/article/details/18820517 //---------------------------------------------------------------------------------------// int no_visit(BTNode** a,int j,BTNode* b); void houxu1(BTNode* head) { BTNode *st[MaxSize],*p=head; int top=-1,topmark; BTNode *visited[MaxSize];int v=0;//visited数组用于存放已经访问过的结点 st[++top]=p; while(true){ while(p->lchild || p->rchild) { topmark=top;//右儿子先进,再左儿子进 if(p->rchild && no_visit(visited,v,p->rchild))st[++top]=p->rchild;//已被访问的就不要进栈了 if(p->lchild && no_visit(visited,v,p->lchild))st[++top]=p->lchild; if(topmark==top)//有儿子但是均被访问过了 { p=st[top--]; cout<<p->data; visited[v++]=p; if(top==-1)goto mark;//返回到了树顶了 p=st[top];//继续返回 } p=st[top]; }//以下是无儿子情况 p=st[top--]; cout<<p->data; visited[v++]=p; if(top==-1)break;//当树只有一个元素既是树顶,就会执行这条语句 p=st[top];//继续返回 } mark:; } int no_visit(BTNode** a,int j,BTNode* b)//判断是否被访问过 { for (int i = 0; i < j; ++i) if(a[i]==b)return 0; return 1; } //---------------------------------------------------------------------------------------// void houxu2(BTNode* head) {int k; BTNode *st[MaxSize],*p=head; int top=-1; st[++top]=p; while(true){ while(p->lchild || p->rchild) { //只有有儿子就行 ,就得进栈,先右儿子,再左儿子 if(p->rchild )st[++top]=p->rchild; if(p->lchild )st[++top]=p->lchild; p=st[top]; } //以下是无儿子情况 p=st[top--]; cout<<p->data;//无儿子就出栈 if(top!=-1)//一个儿子被访问过了,这个儿子就消失吧。888 { if(st[top]->rchild==p) st[top]->rchild=NULL;///使其变成无儿子情况 if(st[top]->lchild==p) st[top]->lchild=NULL;///使其变成无儿子情况 } if(top > 0 ){ if(st[top-1]->rchild==p) st[top-1]->rchild=NULL;///使其变成无儿子情况 if(st[top-1]->lchild==p) st[top-1]->lchild=NULL;//使其变成无儿子情况 } free(p);//886 if(top==-1)break;//返回到了树顶了 p=st[top]; } } //---------------------------------------------------------------------------------------//
原文:http://blog.csdn.net/h1023417614/article/details/18839447