二叉树的创建及递归和非递归遍历

来源:互联网 发布:网络视频广告费用 编辑:程序博客网 时间:2024/05/22 14:16

一直知道个大概,没动手实现过,今天自己总结了下,以下图二叉树为例:


下面是创建二叉树,递归和非递归遍历的完整代码实现如下。

#include <iostream>#include <stdio.h>#include <stack>using namespace std;typedef struct BinNode{char data;bool flag;           //后序非递归中的标记struct BinNode *lchild,*rchild;}BinNode,*BinTree;//按先序创建树 ABD##E##CF####void creatTree(BinTree &T){char c;cin>>c;if(c=='#')T=NULL;else{T=(BinTree)malloc(sizeof(BinNode));T->data=c;creatTree(T->lchild);creatTree(T->rchild);}}void visit(BinTree T){if(T->data!='#')cout<<T->data<<" ";}void preOrder(BinTree T)               //前序递归{if(T){visit(T);preOrder(T->lchild);preOrder(T->rchild);}}void inOrder(BinTree T)             //中序递归{if(T){inOrder(T->lchild);visit(T);inOrder(T->rchild);}}void postOrder(BinTree T)          //后序递归{if(T){postOrder(T->lchild);postOrder(T->rchild);visit(T);}}void preOrderUnrec(BinTree T)           //非递归前序遍历{BinTree p;p=T;stack<BinTree> s;while(p || !s.empty()){while(p){visit(p);s.push(p);p=p->lchild;}if(!s.empty()){p=s.top();s.pop();p=p->rchild;}}}void inOrderUnrec(BinTree T)             ////非递归中序遍历{BinTree p;p=T;stack<BinTree> s;while(p || !s.empty()){while(p){s.push(p);p=p->lchild;}if(!s.empty()){p=s.top();visit(p);s.pop();p=p->rchild;}}}void postOrderUnrec1(BinTree T)    //非递归后序遍历  这个思路更好理解一些,下面有解释{BinTree p,cur;BinTree pre=NULL;p=T;stack<BinTree> s;s.push(p);while(!s.empty()){cur=s.top();if((cur->lchild==NULL && cur->rchild==NULL)||((pre!=NULL)&&(pre==cur->lchild || pre==cur->rchild))){visit(cur);s.pop();pre=cur;}else{if(cur->rchild)s.push(cur->rchild);if(cur->lchild)s.push(cur->lchild);}}}void postOrderUnrec2(BinTree T)    //非递归后序遍历{BinTree p,cur;p=T;stack<BinTree> s;p->flag=false;s.push(p);while(!s.empty()){cur=s.top();if(cur->flag==true){visit(cur);s.pop();               }else{if(cur->rchild){cur->rchild->flag=false;s.push(cur->rchild);}if(cur->lchild){cur->lchild->flag=false;         // 左右节点为NULL时,开始要出栈     s.push(cur->lchild);}cur->flag=true;            //左右子节点入栈后,父节点标记为TRUE}}}int main(){BinTree T;creatTree(T);cout<<"preOrder  :"<<endl;preOrder(T);           //前序cout<<endl;cout<<"preOrderUnrecursion  :"<<endl;preOrderUnrec(T);cout<<endl;cout<<"inOrder  :"<<endl;inOrder(T);            //中序cout<<endl;cout<<"inOrderUnrecursion  :"<<endl;inOrderUnrec(T);cout<<endl;cout<<"postOrder  :"<<endl;postOrder(T);         //后序cout<<endl;cout<<"postOrderUnrecursion  :"<<endl;postOrderUnrec1(T);cout<<endl;postOrderUnrec2(T);cout<<endl;return 0;}

其中非递归的后序遍历第一种方法postOrderUnrec1(BinTree T) 的思想:要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。该方法摘自http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html

                                             
0 0