二叉树的递归遍历及非递归遍历

二叉树的基本操作——创建、输出、查找、删除_yyy_zxc的博客-CSDN博客_二叉树的创建与输出创建二叉树过程:/*-----------第一轮循环:ch = A;p->data保存结点值b==NULL,b=p将p保存为根结点ch = (第二轮循环:top = 0;St[0] = p = A ,St保存上一个结点k=1ch = B第三轮循环:p->data保存结点值根据上一轮循环的k值判断ch为左孩子还是右孩子,k=1所以将 p保存为左孩子https://blog.csdn.net/yyy_zxc/article/details/124154037 

#include"tree.cpp"		//包含了二叉树的基本算法

//---------------------先序遍历---------------
/*根 --左 --右*/
void Preorder(BTNode *b){
	if(b!=NULL){
		printf("%c",b->data);	//访问结点
		Preorder(b->lchild);	//递归遍历左子树 
		Preorder(b->rchild);	// 递归遍历右子树 
	}
} 

//-----非递归遍历算法
void Preorder1(BTNode *b){
	BTNode *St[MaxSize],*p;		//St[]为存储双亲结点的栈 
	int top = -1;		//栈顶指针 
	if(b!=NULL){
		top++;		
		St[top] = b;	//根结点进栈
		while(top>-1){		//栈空时结束循环
			p=St[top];		//退栈并访问该节点
			top--;
			printf("%c",p->data); //访问结点
			if(p->rchild != NULL){	//有右孩子,将其进栈
				top++;
				St[top] = p->rchild; 
			}
			if(p->lchild != NULL ){		//有左孩子,将其进栈
				top++;
				St[top]	= p->lchild; 
			}		//右孩子先进栈,利用的是栈先进后出的原理 
		} 
	}
	printf("\n"); 
} 

//------------中序遍历--------------
//左 根 右

//递归遍历
void Inorder(BTNode *b){
	if(b!=NULL){
		Inorder(b->lchild);
		printf("%c",b->data);		//访问结点
		Inorder(b->rchild);		// 递归遍历右子树 
			
	}	
} 

//非递归遍历
void Inorder1(BTNode *b){
	BTNode *St[MaxSize],*p;
	int top=-1;
	if(b != NULL){
		p=b;
		while(top>-1 || p!= NULL){
			while(p!=NULL){		//扫描p结点下的所有左子树,并进栈 ,p也进栈 
				top++;
				St[top] = p; 
				
				p = p->lchild;
			}
					//此时已经退出第二层循环 
			if(top>-1){
				p=St[top];	//p结点出栈,并访问
				top--;
				printf("%c",p->data);
				p = p->rchild;	//p指向右孩子 
			}
		}
		printf("\n");
	}
} 

//--------------后序遍历 ---------
//  左---右---根

//递归遍历
void Postorder(BTNode *b){
	if(b != NULL){
		Postorder(b->lchild);	//递归调用左子树
		Postorder(b->rchild);
		printf("%c",b->data);	//访问根结点 
	}
} 

//非递归遍历

void Postorder2(BTNode *b){
	BTNode *St[MaxSize],*p;
	int top=-1;
	bool flag;
	if(b!=NULL){
		do{
			while(b!=NULL){		//遍历b结点左子树 
				top++;
				St[top] =b;
				b = b->lchild;
			}
			p=NULL;		//p指向当前结点的前一个已访问的结点
			flag = true;	//flag为真表示正在处理栈顶结点
			while(top!=-1 && flag){
				b = St[top];	//取出当前的栈顶元素
				if(b->rchild==p){	//若右子树不存在或已被访问,则访问该结点 
					printf("%c",b->data);	//访问b结点
					top--;
					p = b;	//p指向被访问的结点 
				} else{
					b=b->rchild;	//b指向右子树
					flag=false;		//表示当前不是处理栈顶结点 
				} 
			} 
		}while(top!=-1);
		printf("\n");
	}
	
}

//层次遍历
/*
算法思想:
1、初始化一个辅助队列
2、根结点入队【存的是指针而不是结点本身,所以是	Qu[rear] = b;而不是	Qu[rear] = b->data;】
3、若队列非空,则队头结点出队,访问该结点,并将该结点的左右孩子插入队尾
4、重复,直到队列为空 
*/ 

void TravLevel(BTNode *b){
	BTNode *Qu[MaxSize];	//定义环形队列
	int front,rear;			//定义队首和队尾指针
	front = rear =0;		//初始化队列
//	if(b!=NULL)
//		printf("%c",b->data);	//访问根结点
	rear++;
	Qu[rear] = b;			//根结点进队
	while(rear != front){	//队列不为空
		front = (front + 1)%MaxSize;	//队头结点出队,并访问该结点 
		b = Qu[front];					//front指向结点已出队 
		printf("%c",b->data);
		if(b->lchild != NULL){			//若有左孩子,将左孩子入队
			 rear = (rear+1)%MaxSize;
			 Qu[rear] = b->lchild;
		} 
		if(b->rchild != NULL){			//若有右孩子,将右孩子入队
			 rear = (rear+1)%MaxSize;
			 Qu[rear] = b->rchild;
		} 
	} 
	printf("\n"); 
} 

/*
方法二
 1、初始化一个辅助队列
2、访问根结点,并入队【存的是指针而不是结点本身】
3、若队列非空,则队头结点出队,访问该结点的左右孩子,并将左右孩子插入队尾
4、重复,直到队列为空 
*/

void TravLevel01(BTNode *b){
	BTNode *Qu[MaxSize];
	int front,rear;
	front = rear = 0;
	if(b!=NULL)
		printf("%c",b->data);
	rear++;
	Qu[rear] = b; 
	while(rear != front){
		front = (front+1)%MaxSize;
		b = Qu[front];
		if(b->lchild != NULL){
			printf("%c",b->data);
			rear = (rear+1)%MaxSize;
			Qu[rear] = b->lchild;
		} 
		if(b->rchild!=NULL){
			printf("%c",b->data);
			rear = (rear+1)%MaxSize;
			Qu[rear] = b->rchild;
		}
		
	}
	printf("\n");
}


int main(){
	BTNode *b;
	printf("创建二叉树\n");
	CreatBTree(b,"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I))");
	printf("输出二叉树");  DispBTree(b);printf("\n"); 
	printf("层次遍历二叉树:\n");
	printf("方法一:");
	TravLevel(b);
	printf("方法二:");
	TravLevel01(b);
	printf("-----先序遍历二叉树:\n");
	printf("递归:");
	Preorder(b);printf("\n");
	printf("非递归:");
	Preorder1(b);
	printf("-----------中序遍历二叉树:\n");
	printf("递归:");printf("\n");
	Inorder(b);
	printf("非递归:");
	Inorder1(b);
	printf("---------------------后序遍历二叉树:\n");
	printf("递归:");printf("\n");
	Postorder(b);
	printf("非递归:");
	Postorder2(b);
	printf("释放二叉树\n");
	DestroyBTree(b);
	return 1; 
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值