二叉树-顺序-先序-中序-后序遍历---递归-非递归算法实现

二叉树的四大遍历方法
顺序-先序-中序-后序*
一、顺序:按照二叉树的至上而下,从左至右的顺序依次访问结点。
例:ABCDEFGHI
在这里插入图片描述
代码实现

结构体,双链表式,下面同
//二叉链表的存储方式
typedef struct TNode{
	int data;
	struct TNode *Lchild;
	struct TNode *Rchild;
}TNode,*BiTree; 

①顺序遍历的实现:用队列来实现,进队后再访问。 通过访问队头并将队头结点的左右孩子依次入队。循环遍历队列。

//顺序遍历实现  入队后访问
 void LevelOrder(BiTree T){
 	//借助队列来实现
	 /*
	 	根入队,遍历队列:输出队头,如果队头有左孩子那么左孩子入队,如果有右孩子那么右孩子入队。 
	 */ 
	 InitQueue(Q);//初始化空队列
	 BiTree p = T;//p指向树根
	 EnQueue(Q,p);//根入队
	 while(!isEmptyQueue(Q)){
	 	DeQueue(Q,p);//出队 
	 	visit(p->data);//访问
		if(p->Lchild){//有左孩子 -入队 
			EnQueue(Q,p->Lchild);
		}//end-if
		if(p->Rchild){//有右孩子 -入队 
			EnQueue(Q,p->Rchild); 
		}//end-if 
	 }//end-while 
 }//end-function

二、先序遍历: 根-左-右
例:ABDEGHCFI
在这里插入图片描述
①先序遍历递归是实现:

//先序遍历的递归实现
void PreOrder2(BiTree T){
	//根-左-右 
	if(T){
		visit(T->data);
		PreOrder2(T->Lchild);
		PreOrder2(T->Rchild);
	}//end-if
}//end-function 

②先序遍历非递归实现:用栈来过度。先访问再入栈

//先序遍历的非递归实现,入栈前访问 
void PreOrder(BiTree T){
 	//借助栈来实现
	/*
		访问根结点,并入栈,遍历左并入栈,直到为空,再遍历栈顶的右,-循环 
	*/
	InitStack(S);//初始化空栈
	BiTree p = T;//p指向树根,下面对p操作
	while(p || !isEmptyStack(S)){
		if(p){//如果不为空,将左边的依次入栈 
			visit(p->data);//访问结点 
			Push(S,p);//入栈 
			p = p->Lchild; 
		}//end-if
		else{//没有左孩子的时候 
			Pop(S,p);//出栈,但不访问
			p = p->Rchild;//第一遍是遍历最后一个的右子树 
		}//end-else 
	}//end-while 	 
}//end-function

三、中序: 左-根-右
例:DBGEHAFIC
在这里插入图片描述
①中序遍历递归实现:

//中序遍历的递归实现  
void InOrder2(BiTree T){
	//左-根-右 
	if(T){
		InOrder(T->Lchild);
		visit(T->data);
		InOrder(T->Rchild);
	}//end-if
}//end-function

②中序遍历非递归实现:

//中序遍历的非递归实现 入栈后访问 
void InOrder(BiTree T){
	//左-根-右
	InitStack(S);//初始化空栈
	BiTree p = T;//p指向树根,下面对p操作
	while(p || !isEmptyStack(S)){
		if(p){
			Push(S,p);//入栈p
			p = p->Lchild;//左 
		}//end-if
		else{
			Pop(S,p);//出栈p
			visit(p->data);//访问之 
			p = p->Rchild;//右 
		}//end-else 
	}//end-while 
}//end-function 

四、后序: 左-右-根
例:DGHEBIFCA
在这里插入图片描述
①后序遍历递归实现:

//后序遍历的递归实现
void PostOrder2(BiTree T){
	if(T){
		PostOrder2(T->Lchild);
		PostOrder2(T->Rchild);
		visit(T->data);
	}//end-if
}//end-function 

②后序遍历非递归实现:需要判断是否右孩子是否已经访问过。

//后序遍历的非递归实现    入栈后访问
void PostOrder(BiTree T){
	//
	InitStack(S);//初始化空栈 
	BiTree p = T;//p指向树根,下面对p操作 
	BiTree r = NULL;//设定一个指针,指向刚访问过的结点 
	while(p || !isEmptyStack(S)){
		if(p){
			Push(S,p);//入栈
			p = p->Lchild;//左 
		}//此时p为NULL 
		else{
			GetTop(S,p);//获得栈顶,既是最后一个没有左孩子的结点 
			if(p->Rchild && p->Rchild != r){
				//结点有右孩子,且未访问过
				Push(S,p);//入栈
				p = p->Rchild;//右-下个循环访问它的左 
			}//end-if
			else{
				//没有右孩子或右孩子已经访问过
				Pop(S,p);//出栈
				visit(p->data);//访问 
				r = p;//指向刚访问的结点
				p = NULL;//置空,下个循环从栈顶开始  
			}//end-else
		}//end-else 
	}//end-if
}//end-function

非递归时用栈来过度,着实不错!! 当然顺序遍历用队列来操作方便

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值