C_树----遍历二叉树

二叉树遍历就是如何按某条搜索路径巡访树中的每个结点,使得每个结点均被访问依次,而且仅被访问一次。

函数定义:

/*创建空二叉树*/
InitBiTree(T)

/*二叉树的创建*/
CreateBiTree(T)

/*先序遍历二叉树*/ 
PreOrderTraverse(T)

/*中序遍历二叉树*/
InOrderTraverse(T)

/*后续遍历二叉树*/
PostOrderTraverse(T)

/*求二叉树的高度*/
High(T)

/*求二叉树的结点数目*/
Count(T)

/*实现左右子树交换*/
exchange(T)

三种不同遍历的定义:


先序遍历

1)访问根
2)先序遍历左子树
3)先序遍历右子树
/*先序遍历二叉树*/ 
void PreOrderTraverse(BiTNode *p)
{			
	if(p!=NULL)		
	{
		printf("%d ",p->data);
		PreOrderTraverse(p->lchild);
		PreOrderTraverse(p->rchild);
	}
}

前序非递归遍历二叉树
/*前序非递归遍历二叉树:栈*/
Status PreOrderTraverse(BiTree T)
{
	stack S;
	InitStack(S);
	BiTree p=T;			//p指向当前访问的结点
	
	while(p||!StackEmpty(S))
	{
		if(p)
		{
			printf("%c",p->data);
			Push(S,p);
			p=p->lchild;			
		}else{
			Pop(S,p);
			p=p->rchild;
		}
	}
	return OK;
}


中序遍历

1)中序遍历左子树
2)访问根结点
3)最后中序遍历右子树
/*中序遍历二叉树*/
void InOrderTraverse(BiTNode *p)
{
	if(p!=NULL)
	{
		PreOrderTraverse(p->lchild);
		printf("%d ",p->data);
		PreOrderTraverse(p->rchild);
	}
}
中序非递归遍历二叉树
/*中序非递归遍历二叉树:栈*/
Status InOrderTraverse(BiTree T)
{
	stack S;
	BiTree p;
	InitStack(S);
	Push(S,T);
	while(!StackEmpty(S))
	{
		while(GetTop(S,p)&&p)
			Push(S,p->lchild);	//向左走到尽头 
		Pop(S,p);				//空指针退栈(叶子的左孩子)
		if(!StackEmpty(S))
		{//访问结点,向右一步 
			Pop(S,p);
			printf("%d",p->data);			//当前根结点
			Push(S,p->rchild); 
		} 
	}
	return OK;
}

/*中序非递归遍历二叉树:栈*/
Status InOrderTraverse(BiTree T)
{
	stack S;
	InitStack(S);
	BiTree p=T;
	while(p||!StackEmpty(S))
	{
		if(p)
		{						//非空指针进栈,继续左进	 
			Push(S,p);
			p=p->lchild;
		}else{					//上层指针退栈,访问其所指结点,再向右进 
			Pop(S,p);
			printf("%d",p->data);
			p=p->child; 
		}
	}
	return OK;
} 


后序遍历

1)首先后序遍历左子树
2)再后序遍历右子树
3)最后访问根
/*后续遍历二叉树*/
void PostOrderTraverse(BiTNode *p)
{
	if(p!=NULL)
	{
		PostOrderTraverse(p->lchild);
		PostOrderTraverse(p->rchild);
		printf("%d ",p->data);
	}
}

后续遍历二叉树:
/*后序非递归遍历二叉树:栈*/
Status PostOrderTraverse(BiTree T)
{
	stack S;
	InitStack(S);
	BiTree p=T;
	pre=NULL;
	while(p||!StackEmpty(S))
	{
		if(p){
			Push(S,p);
			p=p->left;
		}else{
			Pop(S,p);
			if(p->right!=NULL&&pre!=p->right)
			{//pre指向上次访问的右结点,避免再次访问 
				p=p->right;
			}else{
				printf("%d",p->data);
				pre=p;
				p=NULL;
			}
		}
	}
}


/*后序非递归遍历二叉树:栈*/
Status PostOrderTraverse(BiTree T) 
{
    BiTree p = T,last = NULL;
    stack S;
    InitStack(S);
    Push(S,p);
    while(!StackEmpty(S))
    {
        Pop(S,p);
        if(last == p->left || last == p->right)//左右子树已经访问完了,该访问根节点了
        {
            printf("%d",p->data);
            last = p;
        }
        else if(p->left || p->right) //左右子树未访问,当前节点入栈,左右节点入栈
        {
            Push(S,p);
            if(p->right)
                Push(S,p->right);
            if(p->left)
                Push(S,p->left);
        }
        else //当前节点为叶节点,访问
        {
            printf("%d",p->data);
            last = p;
        }
    }
}



层次遍历二叉树
/*按照层次遍历二叉树*/
void LevelOrderTraverse(BiTree T)
{
    Queue BiNodeQueue;
    BiTree p=T;
    EnQueue(BiNodeQueue,p);
    while(!BiNodeQueue.Empty())
    {
        DeQueue(BiNodeQueue,p);
        if(p)
        {
            printf("%c",p->data);
            EnQueue(BiNodeQueue,p->lchild);
            EnQueue(BiNodeQueue,p->rchild);
        }
    }
} 


下面还给了求二叉树结点个数、寻找树的高度和左右子树互换实现:
/*求二叉树的结点数目*/
Status Count(BiTree T)
{
	if(T==NULL)
	{
		return 0;
	}
	return Count(T->lchild)+Count(T->rchild)+1;
}

/*求二叉树的高度*/ 
Status High(BiTNode *p)
{
	int lh=0;
	int rh=0;
	if(p==NULL)
	{
		return 0;
	}
	lh=High(p->lchild);
	rh=High(p->rchild);
	if(lh>rh)			//求二叉树的遍历左右子树返回最大的那一个值 
	{
		return lh+1;		 
	}
	else
	{
		return rh+1;
	}
}

/*实现左右子树交换*/ 
Status exchange(BiTree T)
{
	if(T==NULL){
		return 0;		
	}else{
		BiTree temp=T->lchild;
		T->lchild=T->rchild;
		T->rchild=temp;
		exchange(T->lchild);
		exchange(T->rchild);
	}
	
}

嗯下面就是在VC中的测试:
#include<stdio.h>
#include<stdlib.h> 
#define ERROR 0
#define OK 1
typedef int Status; 
typedef int ElemType;
typedef	struct BiTNode
{
	ElemType	data;
	struct	BiTNode	*lchild;
	struct	BiTNode	*rchild;
}BiTNode,*BiTree;

/*创建空二叉树*/
Status InitBiTree(BiTree &T)
{
	T=NULL;
	return OK;
}

/*二叉树的创建*/
Status CreateBiTree(BiTree &T)
{
	int ch;
	printf("请输入存放到树中的数据元素:");
	scanf("%d",&ch);
	if(ch==-1){			//截止二叉树的创建 
		T=NULL;
		return ERROR; 
	}else{
		T=(BiTNode*)malloc(sizeof(BiTNode));//申请结点空间
		if(!T)
		{
			printf("二叉树创建失败!\n");
			return ERROR; 
		}else{
			printf("%d成功放入树中\n",ch); 
			T->data=ch;
			CreateBiTree(T->lchild);	//构造左子树
			CreateBiTree(T->rchild);	//构造右子树
			return OK; 
		} 
	} 
}

/*先序遍历二叉树*/ 
void PreOrderTraverse(BiTNode *p)
{			
	if(p!=NULL)		
	{
		printf("%d ",p->data);
		PreOrderTraverse(p->lchild);
		PreOrderTraverse(p->rchild);
	}
}

/*中序遍历二叉树*/
void InOrderTraverse(BiTNode *p)
{
	if(p!=NULL)
	{
		PreOrderTraverse(p->lchild);
		printf("%d ",p->data);
		PreOrderTraverse(p->rchild);
	}
}

/*后续遍历二叉树*/
void PostOrderTraverse(BiTNode *p)
{
	if(p!=NULL)
	{
		PostOrderTraverse(p->lchild);
		PostOrderTraverse(p->rchild);
		printf("%d ",p->data);
	}
}

/*求二叉树的高度*/ 
Status High(BiTNode *p)
{
	int lh=0;
	int rh=0;
	if(p==NULL)
	{
		return 0;
	}
	lh=High(p->lchild);
	rh=High(p->rchild);
	if(lh>rh)			//求二叉树的遍历左右子树返回最大的那一个值 
	{
		return lh+1;		 
	}
	else
	{
		return rh+1;
	}
}

/*求二叉树的结点数目*/
Status Count(BiTree T)
{
	if(T==NULL)
	{
		return 0;
	}
	return Count(T->lchild)+Count(T->rchild)+1;
}

/*实现左右子树交换*/ 
Status exchange(BiTree T)
{
	if(T==NULL){
		return 0;		
	}else{
		BiTree temp=T->lchild;
		T->lchild=T->rchild;
		T->rchild=temp;
		exchange(T->lchild);
		exchange(T->rchild);
	}
	
}

int main()
{
	int ch;
	BiTree T;
	CreateBiTree(T);
	printf("**********************************\n");
	printf("1、先序遍历二叉树\n2、中序遍历二叉树\n3、后序遍历二叉树\n");
	printf("4、输出二叉树高度\n5、输出结点的数目\n6、左右的子树交换\n");
	printf("输入0退出操作\n");
	printf("**********************************\n");
	printf("请输入要进行的操作:");
	while(scanf("%d",&ch)&&ch!=0)
	{ 
		if(ch==1){
			PreOrderTraverse(T);
			printf("\n");
		}
		if(ch==2){
			InOrderTraverse(T);
			printf("\n");
		}
		if(ch==3){
			PostOrderTraverse(T);
			printf("\n"); 
		}
		if(ch==4){
			printf("二叉树的高度为%d\n",High(T));
		}
		if(ch==5){
			printf("二叉树的结点数目为%d\n",Count(T));
		}
		if(ch==6){
			exchange(T);
			printf("二插树左右子树成功交换\n"); 
		}
	printf("请输入要进行的操作:");		
	}
	return 0;
} 





  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值