二叉树的性质及二叉树基本遍历

一、二叉树的基本性质

        先介绍一下二叉树,二叉树是数据结构中一种特殊的树形结构,也就是每个节点最多有俩个子树,即二叉树中不存在度大于二的节点(度表示一个节点的子树个数),而且二叉树有左右之分,顺序不能颠倒。

        二叉树又有俩种特殊的二叉树,即满二叉树和完全二叉树。

满二叉树:

        若一棵树的层数为k,它总结点数是2^k-1,则这棵树就是满二叉树。

完全二叉树:

        若一棵树的层数为k,它前k-1层的总结点数是2^(k-1)-1,第k层的结点按照从左往右的顺序排列,则这棵树就是完全二叉树。

性质一:在二叉树的第i层上,最多有2^(i-1)个结点。

        二叉树有且只有一个根节点,每个节点最多有俩个子树,所以第一层为一个节点,第二层最多为俩个节点,第三层最多为四个节点,可以发现规律,第i层最多有2^(i+1)个节点。

性质二:深度为k的二叉树,最多有2^k-1个节点。

        由性质一可知,第i层的子树最多有2^(i-1)个节点,则前i层的节点数最多为2^k-1

性质三:

对于任何一棵二叉树,如果叶子结点的数量为n0,度为2结点的数量为n2,则n0=n2+1;

总数n 叶子节点n0 求度1的节点数 n1 = n- n0-(n0-1) 度2节点n2 = n0-1

性质四:具有n个结点的完全二叉树的高度为(log2n)+1

性质五:

有一个n个结点的完全二叉树,结点按照从上到下从左到右的顺序排序为1~n。

1、i > 1时,i/2就是它的双亲结点。

2、i*2是i的左子树,当i*2>n时,则i没有左子树。

3、2*i+1是i的右子树,2*i+1>n时,则i没有右子树。

二、二叉树的基本遍历

1、前序遍历:

1、判断二叉树是否为空,若二叉树为空,则不操作。

2、访问根结点

3、前序遍历左子树

4、前序遍历右子树

        以此图为例,则前序遍历为:A B D G E H I C FJ

        二叉树的遍历都需要用到递归的思想,为了方便实现,定义了一个字符串为二叉树的输入

“ABCDE#FG#HI##J”,‘#’号表示为当前位置没有子树。

定义一个顺序二叉树结构

// 顺序二叉树结构
typedef struct BinTree
{
	TREE_TYPR* ptr;
	size_t cap;
}BinTree;

接下来构建一个二叉树

// 构建二叉树
// 根据提供的完全二叉树层序遍历的结果,来构建一个堆内存中的二叉树
BinTree* create_tree(TREE_TYPR* arr,size_t len)
{
	BinTree* tree = malloc(sizeof(BinTree));
	tree->ptr = malloc(sizeof(TREE_TYPR)*len);
	memcpy(tree->ptr,arr,sizeof(TREE_TYPR)*len);
	tree->cap = len;
	return tree;
}

实现前序遍历函数,需要用到递归的思想。

void _dlr_show(BinTree* tree,size_t index)
{
	if(index>tree->cap || tree->ptr[index-1] == ‘#’)
		return;

	// 访问根节点
	printf(“%c”,tree->ptr[index-1]);
	// 对左子树前序遍历
	_dlr_show(tree,2*index);
	// 对右子树前序遍历
	_dlr_show(tree,2*index+1);
}

void dlr_show(BinTree* tree)
{
	_dlr_show(tree,1);	
	printf("\n");
}

2、中序遍历:

1、判断二叉树是否为空,若二叉树为空,则不操作。

2、中序遍历左子树

3、访问根结点

4、中序遍历右子树

中序遍历为 G D B H E I A C J F

void _ldr_show(BinTree* tree,size_t index)
{
	if(index>tree->cap || tree->ptr[index-1] == '#')
		return;
	_ldr_show(tree,2*index);
	printf("%c ",tree->ptr[index-1]);
	_ldr_show(tree,2*index+1);
}

void ldr_show(BinTree* tree)
{
	_ldr_show(tree,1);
	printf("\n");
}

3、后序遍历:

1、判断二叉树是否为空,若二叉树为空,则不操作。

2、后序遍历左子树

3、后序遍历右子树

4、访问根结点

后续遍历为G D H I E B J F C A

void _lrd_show(BinTree* tree,size_t index)
{
	if(index>tree->cap || tree->ptr[index-1] == '#')
		return;
	_lrd_show(tree,index*2);
	_lrd_show(tree,2*index+1);
	printf("%c ",tree->ptr[index-1]);	
}

void lrd_show(BinTree* tree)
{
	_lrd_show(tree,1);
	printf("\n");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值