二叉树的遍历(递归,非递归)

二叉树的遍历(递归,非递归)

#include<stdio.h>
#include<string.h>
#include <stdlib.h>
#define MAXSIZE 100 
#define OK 1
#define ERROR 0

//---二叉树的二叉链表存储结构 --- 
typedef struct Tree
{
	char data;
	struct Tree *lchild;
	struct Tree *rchild;
}BiNode,*BiTree;


//-------栈的链式存储-------- 
typedef struct StackNode{
     BiTree data; //特别注意这里栈的数据类型应该是二叉树指针类型,这样才能和以下代码----MMM----处对应 
     struct StackNode *next;
     int stacksize;//栈可用的最大容量 
}StackNode,*LinkStack;



StackNode *q;



//链栈的初始化
int InitStack (LinkStack &S)
{
   S=NULL;
   return OK;
}


//入栈
int Push(LinkStack &S,BiTree e) 
{
	//在栈顶插入元素e
	q=new StackNode;//生成新的节点 
	q->data=e;//将新数据域置为e  
	q->next=S;//将新的元素插入栈顶 
	S=q;//修改栈顶指针为p 
	return OK; 
}



//出栈
BiTree Pop(LinkStack &S) 
{
    //删除S栈顶元素,用e返回其值
    BiTree e;
	if(S==NULL)  return ERROR;//栈空
	e=S->data;//将栈顶元素赋值给e
    q=S;//用p临时保存栈顶空间,以被释放 
	S=S->next;//修改栈顶指针	
	delete q;//释放原栈顶元素的空间 	
	return e;
}


//取栈顶元素
BiTree GetTop(LinkStack S) //特别注意栈顶元素的返回类型  
{
    //返回S的栈顶元素,不修改栈顶指针
	if(S!=NULL) //栈非空
	    return S->data;//返回栈顶元素的值,栈顶指针不变		 
}


//判断栈是否为空 
int StackEmpty (LinkStack S)
{
	if(S==NULL) return OK;
	else return ERROR; 
}

//创建二叉树
BiTree CreateBinTree()
{
	char ch;
	BiTree BT;
	scanf("%c",&ch);
	if (ch == '#')
    {
        BT = NULL;
    }
	else{
		BT=new BiNode; //建立新的节点 
        BT->data=ch;  //将传入的值赋值给新节点的数据域 
        BT->lchild=CreateBinTree();
        BT->rchild=CreateBinTree();
       }
       return BT;
 } 


 

//先序遍历二叉树的递归算法 
void DGpre_InOrderTraverse(BiTree T)
{
	if(T)
    {
		printf("%c",T->data);        //访问根节点
		DGpre_InOrderTraverse(T->lchild);  //中序遍历左子树 
		DGpre_InOrderTraverse(T->rchild); //中序遍历右子树
	}
}



//中序遍历二叉树的递归算法 
void DGcenter_InOrderTraverse(BiTree T)
{
	if(T)
	{
		DGcenter_InOrderTraverse(T->lchild);  //中序遍历左子树 
		printf("%c",T->data);        //访问根节点
		DGcenter_InOrderTraverse(T->rchild); //中序遍历右子树
	}
}


//后序遍历二叉树的递归算法 
void DGlast_InOrderTraverse(BiTree T)
{
	if(T)
	{
		DGlast_InOrderTraverse(T->lchild);  //中序遍历左子树  
		DGlast_InOrderTraverse(T->rchild); //中序遍历右子树
		printf("%c",T->data);              //访问根节点
	}
}



//先序遍历二叉树的非递归算法
void Pre_OderTraverse(BiTree T)
{
	LinkStack S;   //创立栈 
	InitStack(S);  //初始化栈 
	BiTree e,p;  //设置变量e用来存放出栈元素 
	p=T;      //将树的指针变量赋值给p 
	Push(S,p); //根指针进栈 
	while(!StackEmpty(S))//如果栈不为为空 
	{
		p=GetTop(S);
		e=Pop(S);
    	printf("%c",p->data);//访问根节点
    	if(p->rchild)	//右子树不为空 ,先访问右子树,右子树先进栈,则其后出栈 
    	{
    		Push(S,p->rchild);
		}
		if(p->lchild)//左子树不为空 
    	{
    		Push(S,p->lchild);
		}
		
	}		 
		    		
}



//中序遍历二叉树的非递归算法
void In_OderTraverse(BiTree T)
{
	LinkStack S;   //创立栈 
	InitStack(S);  //初始化栈 
	BiTree e,p;  //设置变量e用来存放出栈元素 
	p=T;      //将树的指针变量赋值给p 
	while(p||!StackEmpty(S)) 
	{
		if(p)  //如果树不为空进行以下操作 
		{
			Push(S,p); //根指针进栈 
			p=p->lchild;//根指针进栈,遍历左子树		
	    }
	    else
	    {   
	        p=GetTop(S);// ----MMM----处 返回的栈顶元素是二叉树的指针类型 ,这样可保证栈的指针和树的指针类型相对应 ,便可访问右子树 
		    e=Pop(S);//出栈    (注意得到栈顶元素的次序和出栈的次序,要先得到栈顶元素,再出栈) 
	    	printf("%c",e->data);//访问根节点	
	    	p=p->rchild;//遍历右子树 	    	
		}
	}
	
}



//后序遍历二叉树的非递归算法
void Last_OderTraverse(BiTree T)
{
	LinkStack S;   //创立栈 
	InitStack(S);//初始化栈 
	LinkStack ST;//创立ST栈,为了使最后输出的值是反向的 
	InitStack(ST);  
	BiTree e,L,p;  //设置变量e用来存放出栈元素 
	p=T;      //将树的指针变量赋值给p 
	Push(S,p);//根指针进栈
	while(!StackEmpty(S))//如果栈不为为空 
	{
		p=GetTop(S);
		e=Pop(S);
		p->data;
		Push(ST,p);
    	//此时的访问顺序是根右左,而后序遍历的顺序是左右根,前后位置一反转就好 
		if(p->lchild)//左子树不为空 , 先访问左子树,左子树先进栈,则其后出栈 
    	{
    		Push(S,p->lchild);
		}
		if(p->rchild)//右子树不为空
    	{
    		Push(S,p->rchild);
		}	
	}
	while(ST)//当栈不为空时 
	{
		L=Pop(ST);//栈顶元素出栈,并将其保存在 L中 
		printf("%c",L->data);//输出树的节点 ,实现(根->右->左)向(左->右->根)的转化 
	}
}


//主函数 
main()
{
	int k;//选择 
	BiTree Tr;
	printf("请用先序建立的方式构建二叉树,'#'表示为空:\n");
	Tr=CreateBinTree();//Tr接收CreateBinTree()函数返回的二叉树BT 
	printf("\n");
	printf("\n");
	printf("请选择遍历二叉树的方式:\n---0:递归遍历\n---1:非递归遍历\n---请选择:"); 
	scanf("%d",&k);
	printf("\n");
	if(k==0)
	{
		printf("递归先序遍历二叉树,结果为:");
	    DGpre_InOrderTraverse(Tr);
	    printf("\n");
	    printf("递归中序遍历二叉树,结果为:");
	    DGcenter_InOrderTraverse(Tr);
	    printf("\n");
	    printf("递归后序遍历二叉树,结果为:");
	    DGlast_InOrderTraverse(Tr);
	}
	else if(k==1)
	{
		printf("非递归先序遍历二叉树,结果为:");
	    Pre_OderTraverse(Tr);
	    printf("\n");
	    printf("非递归中序遍历二叉树,结果为:");
	    In_OderTraverse(Tr);
	    printf("\n");
	    printf("非递归后序遍历二叉树,结果为:");
	    Last_OderTraverse(Tr);
	}
	else printf("请根据要求正确选择遍历方式");	
 } 


发布了53 篇原创文章 · 获赞 42 · 访问量 9356
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览