后序遍历二叉树的非递归算法.docx
- 文档编号:12716612
- 上传时间:2023-04-21
- 格式:DOCX
- 页数:17
- 大小:18.42KB
后序遍历二叉树的非递归算法.docx
《后序遍历二叉树的非递归算法.docx》由会员分享,可在线阅读,更多相关《后序遍历二叉树的非递归算法.docx(17页珍藏版)》请在冰豆网上搜索。
后序遍历二叉树的非递归算法
后序遍历二叉树的非递归算法
1.请根据用户输入的“扩展的先序遍历序列”(用小圆点表示空子树),建立以二叉链表方式存储的二叉树,然后写出后序遍历该二叉树的非递归算法。
方法一:
#include
#include
#defineMAX_TREE_SIZE100
typedefstructBiTNode{
chardata;
structBiTNode*lchild;
structBiTNode*rchild;
}BiTNode,*BiTree;
//函数声明
voidPrint(BiTree*root);
voidSelection(intsel,BiTree*root);
voidReadExPreOrder(BiTree*root);
voidPrintExPreOrder(BiTreeroot);
voidPostOrderTraverse(BiTreeT);
//主函数
voidmain(){
BiTreeroot=NULL;//初始化根结点
Print(&root);
while(true){
printf("\nPressentertocontinue.........");
getchar();
getchar();
system("cls");
Print(&root);
}
}
voidPrint(BiTree*root){
//提示
intsel;
printf("使用说明:
本程序可实现二叉链表方式存储的二叉树,输入为扩展先序遍历序列.\n");
printf("---------------------\n");
printf("1.输入扩展先序遍历序列并建立对应的二叉树.\n");
printf("2.打印当前的二叉树的扩展先序遍历序列.\n");
printf("3.后序遍历当前的二叉树并打印遍历序列.\n");
printf("4.按其它任意键退出.\n");
printf("---------------------\n");
printf("请选择你要的操作:
");
scanf("%d",&sel);
getchar();
Selection(sel,root);
}
voidSelection(intsel,BiTree*root){
//根据用户输入决定下一步骤
switch(sel){
case1:
ReadExPreOrder(root);
break;
case2:
PrintExPreOrder(*root);
break;
case3:
PostOrderTraverse(*root);
break;
default:
exit(0);
}
}
voidReadExPreOrder(BiTree*root){
//先序遍历二叉树,root为指向二叉树(或某一子树)根结点的指针
charch;
ch=getchar();
if(ch=='.')
*root=NULL;
else{
(*root)=(BiTree)malloc(sizeof(BiTNode));
(*root)->data=ch;
ReadExPreOrder(&((*root)->lchild));
ReadExPreOrder(&((*root)->rchild));
}
}
voidPrintExPreOrder(BiTreeroot){
charch;
if(root!
=NULL){
ch=root->data;
printf("%c",ch);
PrintExPreOrder(root->lchild);
PrintExPreOrder(root->rchild);
}
else
printf(".");
}
voidPostOrderTraverse(BiTreeT){
BiTreestack[MAX_TREE_SIZE],p;
inttag[MAX_TREE_SIZE],top=0;
p=T;
while(p||top!
=0){
while(p){
top++;
stack[top]=p;
tag[top]=0;
p=p->lchild;//从根开始,左结点依次入栈
}
if(top>0){
if(tag[top]==1){//表示是从该结点的右子树返回,则访问该结//点
p=stack[top];
printf("%c",p->data);
top--;
p=NULL;//将p指向NULL,则下次进入while循环时,不做左子//树入栈操作
}
else{//表明是从该结点左子树返回,应继续访问其右子树
p=stack[top];
if(top>0){
p=p->rchild;
tag[top]=1;//表明该结点的右子树已访问
}
}//endofelse
}//endofif
}//endofwhile
}
方法二(顺序栈):
#include
usingnamespacestd;
typedefstructnode
{
charch;
structnode*lchild;
structnode*rchild;
}node;
typedefstructbinarytree
{
node*head;//指向根结点
}bt;
intn=0;
voidini(bt*&b)
{
b=newbt;
b->head=NULL;
}
voidprecreate(node*&t)//先序递归建立二叉树
{
cout<<"\n\n请输入结点数据,以'.'代表空:
";
charc;
cin>>c;
if(c=='.')t=NULL;
else
{
n++;
t=newnode;
t->ch=c;
precreate(t->lchild);
precreate(t->rchild);
}
}
//--------------------------------------------------
//非递归算法需要栈
typedefstructstack{
node**base;
node**top;
intstacksize;
}stack;
voidini(stack&s){
s.base=newnode*[100];
s.top=s.base;
s.stacksize=100;
}
voidpush(stack&s,node*elem){
(*s.top++)=elem;
}
voidpop(stack&s,node*&elem){
elem=*(--s.top);
}
intisempty(stack&s){
if(s.base==s.top)return1;
elsereturn0;
}
voidgettop(stack&s,node*&t){
t=*(s.top-1);
}
voidafttraverse(node*t){//后序遍历非递归算法
stacks;
ini(s);
node*lastvist=NULL;
while(NULL!
=t||!
isempty(s)){
while(NULL!
=t){
push(s,t);
t=t->lchild;
}
gettop(s,t);
if(NULL==t->rchild||lastvist==t->rchild){
cout<<""<
pop(s,lastvist);
t=NULL;
}
else
t=t->rchild;
}
}
intmain(){
bt*b;
ini(b);
precreate(b->head);//构造二叉树
cout<<"\n\n后序遍历:
";
afttraverse(b->head);
cout<<"\n\n";
}
方法三(链栈):
#include
#include
typedefstructBiTNode{
charitem;
structBiTNode*lchild,*rchild;
}BiTNode,*Tree;
typedefstructStack{
Treem;
structStack*next;
}Stack,*st;
TreeCreateTree()
{
TreeB;
charch;
ch=getchar();
if(ch=='.')
returnNULL;
else
{
B=(Tree)malloc(sizeof(BiTNode));
B->item=ch;
B->lchild=CreateTree();
B->rchild=CreateTree();
returnB;
}
}
voidPostOrder(TreeT)
{
Treep,q;
sts,top;
intop;
p=T;
top=NULL;
do{
while(p!
=NULL)
{
s=(st)malloc(sizeof(Stack));//使用链表形式存储栈,即//链栈
s->m=p;
s->next=top;
top=s;
p=p->lchild;
}
op=1;//该标志用于控制进入下面的while循环
q=NULL;
while(top!
=NULL&&op==1)
{
if(top->m->rchild==q)//若当前栈顶结点的右孩子是上次访问的结点,则打印该结点
{
printf("%c",top->m->item);//第一次时打印最左下边结点
q=top->m;//q记录上次访问的结点
top=top->next;//栈指针后移,即将该结点从栈中弹出
}
else//若当前栈顶结点的右孩子不是上次访问的结点,则先访问其右孩//子
{
p=top->m->rchild;
op=0;//op用来控制往右走一步后跳出当前while循环,进入下//一次外层的while循环
}
}
}while(top!
=NULL);
}
intmain()
{
TreeT;
printf("pleaseenterthechars:
\n");
T=CreateTree();
PostOrder(T);
getchar();
getchar();
return0;
}
方法四:
#include
#include
structTREE//二叉树结点结构
{
chardata;
structTREE*lsubtree;
structTREE*Rsubtree;
};
structTREE*tree;
voidcreatetree(structTREE*&p)//先序创建二叉树
{
charch;
ch=getchar();
if(ch=='\n')
{
p=NULL;
}
elseif(ch=='.')
p=NULL;
else
{
p=(structTREE*)malloc(sizeof(structTREE));//分配//结点空间
p->data=ch;
createtree(p->lsubtree);//递归创建左子树
createtree(p->Rsubtree);//递归创建右子树
}
}
voidlastorder(structTREE*tree)//非递归后序遍历
{
structTREE*p;
structTREE*s[100];//用一个指针数组来用作栈
inttop=-1;//下标
intmack[100];//标志数组
p=tree;
do{
while(((p->lsubtree)!
=NULL)&&(mack[top+1]!
=2))//循环//直到让p向左滑到最左子树,并且该结点非第二次入栈
{
top=top+1;
s[top]=p;//每循环一次,当前结点入栈
mack[top]=1;//结点第一次入栈时,标志为1
p=p->lsubtree;//找最左子树
}//叶子结点无须入栈
printf("%c\n",p->data);//输出末节点
p=s[top];//出栈顶元素
top=top-1;//每出一个栈顶元素,下标就后退一位
if(mack[top+1]==1)//若结点是第一次出栈,则再入栈
{
top=top+1;
s[top]=p;
mack[top]=2;//结点第二次入栈时,标志为2
p=p->Rsubtree;//访问右子树
}
}while(top!
=-1);//top==-1时,说明根结点刚访问完,跳出循环后//打印
printf("%c\n",s[0]->data);//最后把根输出
}
intmain(){
printf("请输入二叉树数据\n");
createtree(tree);
printf("后序遍历结果:
\n");
lastorder(tree);
getchar();getchar();
}
方法五:
#include
#include
#definemaxsize50
#defineOK1
typedefstructBnode//声明二叉树的数据结构
{
charch;
structBnode*lchild,*rchild;
}bnode,*btree;
typedefstructtype
{
btreenode;
intflag;
}datatype,*pdatatype;
typedefstruct{//声明栈的数据结构
datatypedata[maxsize];
inttop;
}seqstack,*pseqstack;
btreecreatbtree()//创建二叉树
{
inti=0;
btreet;
charc;
c=getchar();
if(c=='#')
{t=NULL;i++;}
else
{
t=(btree)malloc(sizeof(bnode));
t->data=c;i++;
t->lchild=creatbtree();
t->rchild=creatbtree();
}
returnt;
}
intprintelem(/*ElemType*/chare)
{
printf("%c",e);
returnOK;
}
voidpostorder(btreet)//二叉树的后序遍历(非递归)
{//与教材p.131的中序遍历方法类似
pseqstackp;
p=(pseqstack)malloc(sizeof(seqstack));
p->top=0;
while(t||!
(p->top==0))
{
if(t)
{
p->data[p->top].node=t;
p->data[p->top].flag=0;
(p->top)++;
t=t->lchild;
}
else
{
if(p->data[p->top-1].flag==0)
{//若该结点右孩子没有被访问,则先访问其右孩子,并置标志为//1
p->data[p->top-1].flag=1;
t=p->data[p->top-1].node->rchild;//t=t->rchild;
}
else
{//否则直接访问该结点
printf("%c",p->data[p->top-1].node->ch);
(p->top)--;
}
}
}
}
intmain()
{
btreet;
t=creatbtree();
printf("\n后序遍历:
");
postorder(t);
getchar();
getchar();
return0;
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 遍历 二叉 递归 算法
![提示](https://static.bdocx.com/images/bang_tan.gif)