二叉树的全部用法(包括递归、非递归遍历,求高度、叶子结点数、交换左右子树)

1.  二叉树的定义

        二叉树(binary tree)是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树。

2.  二叉树的存储结构

#define TRUE 1					//函数的结构的结果状态
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define INFEASIBLE -2

#define Max_Tree_SIZE 20		//最大结点数

typedef int Status;

typedef char TElemType;

typedef struct BiTNode
{
	TElemType data,n;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

typedef BiTree SElemType;
typedef BiTree QElemType;

3. 初始化一个二叉树

Status InitBiTree(BiTree *BT)		/*构造二叉树*/
{
	*BT = NULL;
	return TRUE;
}

4. 建立二叉树

        通过后序递归建立二叉树,因为后序相对于其他来说比较方便一点。

Status CreateBiTree(BiTree *BT)		/*后序递归建立二叉树*/
{
	char ch;
	scanf_s("%c",&ch);
	if(ch=='#')
		*BT=NULL;
	else{
		*BT=(BiTree)malloc(sizeof(BiTNode));
		CreateBiTree(&(*BT)->lchild);	
		CreateBiTree(&(*BT)->rchild);
		(*BT)->data=ch;
	}
	return OK;
	
}

5  遍历二叉树

5.1 先序遍历二叉树

Status PreOrder(BiTree BT)			/*先序递归遍历*/
{
	if(BT!=NULL){ 
		if( !(BT->data))
			return ERROR;
		printf("%c ",BT->data);
		PreOrder(BT->lchild);
		PreOrder(BT->rchild);
		return OK;
	}
	return OK;
}

运用上图先序遍历结果为:  1 2 4 3 5 6      

记住口诀:中左右。中代码结点,左代表左子树,右代表右子树。

5.2 中序遍历二叉树

Status InOrder(BiTree BT)				/*中序递归遍历*/
{
	if(BT!=NULL)
	{
		InOrder( BT->lchild);
		printf("%c ",BT->data );
		BT->n++;
		InOrder( BT->rchild);
		return OK;
	}
	return OK;
}

遍历结果为:  4 2 1 5 6 3     

 记住口诀:左中右。中代码结点,左代表左子树,右代表右子树。

5.3  后序遍历二叉树

Status PostOrder(BiTree BT)			/*后序递归遍历*/
{
	if(BT!=NULL)
	{
		PostOrder( BT->lchild);
		PostOrder( BT->rchild);
		printf("%c ",BT->data );
		return OK;
	}
	return OK;
}

遍历结果为:  4 2 6 5 3 1    

 记住口诀:左右中。中代码结点,左代表左子树,右代表右子树。

5.4 按层次非递归遍历二叉树

Status LevelOrder(BiTree BT)			/*按层次非递归遍历*/
{
	for(int i=1;i<BT->n;i++)
		if(BT->data!='#')
			printf("%c",BT->data);
	return OK;

}

遍历结果为: 1 2 3 4 5 6 

          在定义二叉树数据结构时候,在每个数当中设置了顺序,所以能直接遍历求得层次遍历。

5.5  先序非递归递归遍历二叉树

Status NRPreOrder(BiTree BT)			/*先序非递归递归遍历*/
{
	BiTree stack[Max_Tree_SIZE],p;
	int top;
	if(BT==NULL)
		return FALSE;
	top=0;
	p=BT;
	while(!(p==NULL&&top==0))
	{
		while (p!=NULL)
		{
			printf("%c",p->data);
			if(top<Max_Tree_SIZE-1)
			{
				stack[top]=p;
				top++;
			}
			else
			{
				printf("溢出");
				return 0;
			}
			p=p->lchild;
		}
		if(top<=0)
			return 0;
		else
		{
			top--;
			p=stack[top];
		}
		p=p->rchild;
	}
	return OK;
}

第一步:将结点数据输出,将其压入栈中,如果存在左孩子,就让结点指向左孩子,并且继续输出结点和压入栈中,直到不存在左孩子,才停止。

第二步:然后把结点出栈,并且每次指向右孩子,如果右孩子为空,则继续出栈;如果不为空,则输出右孩子结点数据,并且压入栈中执行1.

最后一直重复上述过程,直到结点为空且栈为空时候结束。

6 二叉树其他应用

6.1 求二叉树高度

int max(int a,int b)
{
	if(a>b)
		return a;
	else
		return b;
}

int TreeDepth(BiTree BT)				/*求高度*/
{
	if(BT==NULL)
		return 0;
	else
		return max(TreeDepth(BT->lchild),TreeDepth(BT->rchild))+1;
}

           左右递归查出深度最大的子树,就你得出二叉树的高度。

6.2 求二叉树叶子结点数

int LeafNumber(BiTree BT,int &count)			/*求叶结点数*/
{
	
		if(BT){ 
		    LeafNumber(BT->lchild,count);
		    if( (!BT->lchild && !BT->rchild))
			    count++;
		    LeafNumber(BT->rchild,count);
		    return 0;
	    }
	return OK;
}

        左右递归,找出不存在左子树和右子树的结点,然后加一。

6.3 交换二叉树左右结点位置

void change_left_right(BiTree BT)
{
	BiTree p;
	p=(BiTree)malloc(sizeof(BiTNode));
	if(BT)
	{
		change_left_right(BT->lchild);
		change_left_right(BT->rchild);
		p=BT->lchild;
		BT->lchild=BT->rchild;
		BT->rchild=p;
	}
}

        左右递归,如果存在结点不为叶子结点,就将其左右子树进行交互,这里要先建立一个中间变量才能进行交换。

7. 全部代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>

#define TRUE 1					//函数的结构的结果状态
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define INFEASIBLE -2

#define Max_Tree_SIZE 20		//最大结点数

typedef int Status;

typedef char TElemType;

typedef struct BiTNode
{
	TElemType data,n;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

typedef BiTree SElemType;
typedef BiTree QElemType;


Status InitBiTree(BiTree *BT)		/*构造二叉树*/
{
	*BT = NULL;
	return TRUE;
}
Status CreateBiTree(BiTree *BT)		/*后序递归建立二叉树*/
{
	char ch;
	scanf_s("%c",&ch);
	if(ch=='#')
		*BT=NULL;
	else{
		*BT=(BiTree)malloc(sizeof(BiTNode));
		CreateBiTree(&(*BT)->lchild);	
		CreateBiTree(&(*BT)->rchild);
		(*BT)->data=ch;
	}
	return OK;
	
}
Status PreOrder(BiTree BT)			/*先序递归遍历*/
{
	if(BT!=NULL){ 
		if( !(BT->data))
			return ERROR;
		printf("%c ",BT->data);
		PreOrder(BT->lchild);
		PreOrder(BT->rchild);
		return OK;
	}
	return OK;
}
Status InOrder(BiTree BT)				/*中序递归遍历*/
{
	if(BT!=NULL)
	{
		InOrder( BT->lchild);
		printf("%c ",BT->data );
		BT->n++;
		InOrder( BT->rchild);
		return OK;
	}
	return OK;
}
Status PostOrder(BiTree BT)			/*后序递归遍历*/
{
	if(BT!=NULL)
	{
		PostOrder( BT->lchild);
		PostOrder( BT->rchild);
		printf("%c ",BT->data );
		return OK;
	}
	return OK;
}




Status LevelOrder(BiTree BT)			/*按层次非递归遍历*/
{
	for(int i=1;i<BT->n;i++)
		if(BT->data!='#')
			printf("%c",BT->data);
	return OK;

}
Status NRPreOrder(BiTree BT)			/*先序非递归递归遍历*/
{
	BiTree stack[Max_Tree_SIZE],p;
	int top;
	if(BT==NULL)
		return FALSE;
	top=0;
	p=BT;
	while(!(p==NULL&&top==0))
	{
		while (p!=NULL)
		{
			printf("%c",p->data);
			if(top<Max_Tree_SIZE-1)
			{
				stack[top]=p;
				top++;
			}
			else
			{
				printf("溢出");
				return 0;
			}
			p=p->lchild;
		}
		if(top<=0)
			return 0;
		else
		{
			top--;
			p=stack[top];
		}
		p=p->rchild;
	}
	return OK;
}

int max(int a,int b)
{
	if(a>b)
		return a;
	else
		return b;
}

int TreeDepth(BiTree BT)				/*求高度*/
{
	if(BT==NULL)
		return 0;
	else
		return max(TreeDepth(BT->lchild),TreeDepth(BT->rchild))+1;
}
int LeafNumber(BiTree BT,int &count)			/*求叶结点数*/
{
	
		if(BT){ 
		LeafNumber(BT->lchild,count);
		if( (!BT->lchild && !BT->rchild))
			count++;
		LeafNumber(BT->rchild,count);
		return 0;
	}
	return OK;
}

void change_left_right(BiTree BT)
{
	BiTree p;
	p=(BiTree)malloc(sizeof(BiTNode));
	if(BT)
	{
		change_left_right(BT->lchild);
		change_left_right(BT->rchild);
		p=BT->lchild;
		BT->lchild=BT->rchild;
		BT->rchild=p;
	}
}


int main(){
	BiTree BT;
//	TElemType ch;
	BT = (BiTree)malloc(sizeof(BiTNode));
	int flag=1,select,count=0;
	printf("\n");
	printf("To Creat Binary Tree , Please Input PreOrder with ‘#’:");/*输入二叉树的先序序列,用#代表空结点*/
	InitBiTree(&BT);
	CreateBiTree(&BT);			//创建二叉树,返回根节点BT*/
//	PreOrder(BT);
	printf("\n");
//	InOrder(BT);
	printf("\n");
//	PostOrder(BT);


	while(flag){
	printf("Please select:\n");
	printf("1. PreOrder Traversal	\n");
	printf("2. InOrder Traversal	\n");
	printf("3. PostOrder Traversal	\n");
	printf("4. LevelOrder Traversal	\n");
	printf("5. NRPreOrder Traversal	\n");
	printf("6. NRPreOrder Traversal	\n");

	scanf_s("%d",&select);
	switch(select){
	case 1:	printf("\n The PreOrder Traversal of Binary Tree is:");
			PreOrder(BT);			//先序递归遍历
			break;
	case 2:	printf("\n The InOrder Traversal of Binary Tree is:");
			InOrder(BT);			//中序递归遍历
			break;
	case 3:	printf("\n The PostOrder Traversal of Binary Tree is:");
			PostOrder(BT);			//后序递归遍历
			break;
	case 4:	printf("\n The LevelOrder Traversal of Binary Tree is:");
			LevelOrder(BT);			//按层次非递归遍历
			break;
	case 5:	printf("\n The NRPreOrder Traversal of Binary Tree is:");
			NRPreOrder(BT);			//先序非递归递归遍历
			break;
	case 6:	printf("\n The Depth of Binary Tree is:%d",TreeDepth(BT));
								//求高度
			break;

	case 7: LeafNumber(BT,count);//求叶结点数
			printf("\n The Number of leaf is:%d",count);		
			break;
	case 8:	change_left_right(BT);
			break;
	}
	printf("\n");
	}
	getchar();
	getchar();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/study_jiang_up/article/details/129269379