数据结构(五)二叉树及其运用(递归方式)

本文介绍了数据结构中的非线性结构——树和二叉树,重点讲解了二叉树的概念,包括度、叶节点、满二叉树和完全二叉树的定义。此外,还探讨了完全二叉树的识别方法,并总结了二叉树的性质。文章最后阐述了二叉树的四种遍历方式(前序、中序、后序和层次遍历)及其递归实现。
摘要由CSDN通过智能技术生成

数据结构分为线性结构和非线性结构,而这次所讲的树和二叉树为非线性结构。

对于树和二叉树的理解,运用图能更好的让我们去直观的思考。在这之前,我先给大家提几个关于二叉树的慨念。

树:是由n个结点构成的集合。n = 0 的树为空树。

结点:包括一个元素及若干个指向其子树的分支。

结点的度:结点所拥有的子树的个数称为该结点的度。

叶节点:度为 0 的结点,也叫终端结点。

满二叉树:在一棵二叉树中所有分支都有左右孩子,并且所有叶子结点都在同一层。

完全二叉树:如果有一棵具有n个结点的二叉树的结构与满二叉树的前n个结点的结构相同,则称这样的二叉树叫完全二叉树。

总结一下:完全二叉树的最后一个结点的编号是n,则它的父结点的编号为[n/2],则叶子结点个数为n-[n/2]。

下面我把自己对识别完全二叉树的方法总结如下:

1,叶节点的层数之差不能大于 1 ,例如第五个图。

2,结点没有左孩子,一定不能有右孩子,例如第四个图。

3,满二叉树一定是完全二叉树。


二叉树的相关性质:

1,若规定根节点的层数为 0 ,则一颗非空二叉树的第 i 层最多有 2 的 i 次方个结点。

2,若规定只有根节点二叉树深度为 0 ,则深度为 k 的二叉树的最多节点数是 2 的 k + 1 次方减 1 。

3,对于一颗非空二叉树,如果叶节点个数为 n ,度为 2 的结点树为 m,则有 n = m + 1。

二叉树的遍历分为四种:前序遍历(DLR),中序遍历(LDR),后序遍历(LRD),层次遍历。


对于这个二叉树,

前序遍历(DLR):ABDECF

中序遍历(LDR):DBEAFC

后序遍历(LRD):DEBFCA

下面我介绍,二叉树的运用(递归实现),只要有创建二叉树,销毁二叉树,遍历二叉树,和打印二叉树的深度。程序如下:

#include "string.h"
#include "stdio.h"    
#include "stdlib.h"   
#include "math.h"  
#include "time.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100 			// 存储空间初始分配量 

typedef int Status;			// Status是函数的类型,其值是函数结果状态代码,如OK等 
typedef char TElemType; 			// 字符型以空格符为空 
TElemType Nil=' '; 			// 字符型以空格符为空 

typedef struct BiTNode  				// 结点结构 
{
   TElemType data;					// 结点数据 
   struct BiTNode *lchild,*rchild; // 左右孩子指针 
}BiTNode,*BiTree;

Status InitBiTree(BiTree *T)			// 构造空二叉树T 
{ 
	*T=NULL;
	return OK;
}

void CreateBiTree(BiTree *T)
{ 
	TElemType ch;
	printf("请输入字符,输入#结束:\n");	//注意根据你想构造的二叉树的形状来输入相应数量的“#”
	scanf("%c",&ch);
	getchar();
	if(ch=='#') 
		*T=NULL;
	else
	{
		*T=(BiTree)malloc(sizeof(BiTNode));
		if(!*T)
			exit(OVERFLOW);
		(*T)->data=ch; 					//生成根结点 
		CreateBiTree(&(*T)->lchild); 	// 构造左子树 
		CreateBiTree(&(*T)->rchild); 	// 构造右子树 
	}
 }
 
Status BiTreeEmpty(BiTree T)				// 操作结果: 若T为空二叉树,则返回TRUE,否则FALSE
{ 
	if(T)
		return FALSE;
	else
		return TRUE;
}

int BiTreeDepth(BiTree T)				// 初始条件: 二叉树T存在。操作结果: 返回T的深度
{
	int i,j;
	if(!T)
		return 0;							//当结点为空,返回0
	if(T->lchild)
		i = BiTreeDepth(T->lchild);		//遍历左孩子,返回i值
	else
		i = 0;
	if(T->rchild)
		j = BiTreeDepth(T->rchild);		//遍历右孩子,返回j值
	else
		j = 0;
	return i>j?i+1:j+1;
}

TElemType Root(BiTree T)			// 初始条件: 二叉树T存在。操作结果: 返回T的根
{ 
	if(BiTreeEmpty(T))
		return Nil;
	else
		return T->data;
}

void DestroyBiTree(BiTree *T)				// 初始条件: 二叉树T存在。操作结果: 销毁二叉树T
{ 
	if(*T) 
	{
		if((*T)->lchild)						 // 有左孩子 
			DestroyBiTree(&(*T)->lchild); 	//销毁左孩子子树 
		if((*T)->rchild) 						// 有右孩子 
			DestroyBiTree(&(*T)->rchild); 	 //销毁右孩子子树 
		free(*T); 								//释放根结点 
		*T=NULL; 								//空指针赋0 
	}
}

void PreOrderTraverse(BiTree T)
{ 
	if(T==NULL)
		return;
	printf("%c",T->data);		// 显示结点数据
	PreOrderTraverse(T->lchild); //再先序遍历左子树 
	PreOrderTraverse(T->rchild); //最后先序遍历右子树 
}

void InOrderTraverse(BiTree T)
{ 
	if(T==NULL)
		return;
	InOrderTraverse(T->lchild); 	// 中序遍历左子树 
	printf("%c",T->data);		//显示结点数据
	InOrderTraverse(T->rchild);	 //最后中序遍历右子树 
}

void PostOrderTraverse(BiTree T)
{
	if(T==NULL)
		return;
	PostOrderTraverse(T->lchild);	// 先后序遍历左子树  
	PostOrderTraverse(T->rchild); 	// 再后序遍历右子树  
	printf("%c",T->data);			//显示结点数据
}

int main()
{
	int i;
	BiTree T;
	TElemType e1;
	InitBiTree(&T);
	CreateBiTree(&T);
	printf("构造空二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",BiTreeEmpty(T),BiTreeDepth(T));
	e1=Root(T);
	printf("\n前序遍历二叉树:");
	PreOrderTraverse(T);
	printf("\n中序遍历二叉树:");
	InOrderTraverse(T);
	printf("\n后序遍历二叉树:");
	PostOrderTraverse(T);
	printf("\n");
	DestroyBiTree(&T);
	printf("\n清除二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",BiTreeEmpty(T),BiTreeDepth(T));
	return 0;
}
以上就是树二叉树的介绍,程序部分如有不懂,请加qq:2648636032,咨询。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值