二叉树 (操作与一些节点计算题)

二叉树的二叉链表结点结构定义

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

1.前序遍历

前序遍历的规则时若二叉树为空,则空操作返回,否则 先访问根节点,然后前序遍历左子树,在前序遍历右子树,如图:
在这里插入图片描述
这个二叉树的前序遍历就为 ABDGHCEIF。

void PreTraverse(BiTree T)//前序遍历
{
	if (T == NULL)
		return;
	else
	{
		//先打印头结点,然后在先序遍历左孩子,最后在先序遍历右孩子
		printf("%c ", T->data);
		PreTraverse(T->lchild);
		PreTraverse(T->rchild);
	}
}

2.中序遍历

规则是若树为空则返回,否者从根节点开始(这里不是先访问根节点),中序遍历根节点的左子树,然后在访问根节点,最后中序遍历右子树,就还是上面那个图,他的中序遍历为: GDHBAEICF

void InTraverse(BiTree T)//中序遍历
{
	if (T == NULL)
		return;
	else
	{
		//先中序遍历左孩子,然后在打印结点,最后在中序遍历右孩子。
		InTraverse(T->lchild);
		printf("%c ", T->data);
		InTraverse(T->rchild);
	}
}

3.后序遍历

规则是若树为空,则空返回,否则从左到右,先叶子后结点的方式遍历访问左右子树,最后访问根节点 上图的后序遍历为:GHDBIEFCA

void PostTraverse(BiTree T)//后序遍历
{
	if (T == NULL)
		return;
	else
	{
		//先后序遍历左孩子,然后后序遍历右孩子,最后在打印结点。
		PostTraverse(T->lchild);
		PostTraverse(T->rchild);
		printf("%c ", T->data);
	}
}

4.建立二叉树

在这里插入图片描述
普通的树是没有将那些空指针表示出来,这时我们可以对普通的二叉树进行扩展,变成扩展二叉树的样子,我们可以将空指针引出一个虚结点,其值为一特定值,例如 ‘#’。这时我们的前序遍历就会变成:AB#D##C##.

这样我们就可以将先序遍历序列AB#D##C##用键盘输入:

  1. 前序输入
/*按前序输入二叉树中结点的值*/
/* ‘#’表示空树,构造二叉树链表表示二叉树T */
void PreCreateBiTree(BiTree& T)
{
	char ch;
	scanf_s("%c", &ch);
	if (ch == '#')
	{
		T = NULL;
	}
	else
	{
		T = (BiTree)malloc(sizeof(BiTNode));
		if (!T)
			exit(0);
		T->data = ch;
		PreCreateBiTree(T->lchild);
		PreCreateBiTree(T->rchild);
	}
}

2.后序输入
还是这个扩展二叉树,他的后序遍历为:###DB##CA。
如果我们还是向上一个程序那样,只将他的访问顺序改变,而且还是先判断 ch 是否等于 “#” 的话,我们会在开头就结束程序,根本无法建立二叉树。
这时我们观察 后序遍历的结果:###DB##CA,我们从后往前看,首先为根节点,然后再是右节点,然后在左节点。这样的话第一个就不会为 “#” 就可以用后序输入来建立二叉树

/*后序输入,创建二叉树*/
void PostCreateBiTree(BiTree& T,char a[])
{
	static int count = strlen(a);//用静态变量来建立count;
	char ch = a[count - 1];//从后往前
	count--;
	if (ch == '#')
	{
		T = NULL;
	}
	else
	{
		T = (BiTree)malloc(sizeof(BiTNode));
		T->data = ch;
		PostCreateBiTree(T->rchild, a);
		PostCreateBiTree(T->lchild, a);
	}
}

5.复制树

void copy(BiTree T, BiTree& newT)//复制树
{
	if (T = NULL)
		return;
	else
	{
		newT = (BiTree)malloc(sizeof(BiTNode));
		if (!newT)
			exit(0);
		newT->data = T->data;
		copy(T->lchild, newT->lchild);
		copy(T->rchild, newT->rchild);
	}
}

6.求深度

在这里插入图片描述
求深度,我们可以用深搜来解决

void dfs(BiTree T,int m)//深搜来求深度,m用来记录当前深度
{
	if (T == NULL)
	{
		if (max < m)//用max来记录最大的深度
			max = m;
		return;
	}
	else
	{
		/* 向下遍历,m就加一*/
		dfs(T->lchild,m+1);
		dfs(T->rchild,m+1);
	}
}

7.求结点个数

求结点个数同样可以使用深搜来解决,代码如下:

void dfsnode(BiTree T,int ans)//ans为当前的节点数
{
	if (T == NULL)
		return;
	else
	{
		/*向下遍历,ans++*/
		ans++;
		dfsnode(T->lchild);
		dfsnode(T->rchild);
	}
}

节点计算题

在这里插入图片描述
根据完全二叉树的定义,我们可以知道 当结点个数为偶数的时候,度为1的节点个数为 1,即n1=1,但结点个数为奇数的时候,度为1的节点个数为0,即n1=0;然后结点个数为 n=n1+n2+n0;其中n2为度为2的结点,n0叶子结点 ,所以n0=n2+1;
所以这题中 n=768,为偶数,所以 n1=1 ,所以 n=1+2*n0-1=768;
所以 n0=384;

在这里插入图片描述
根据完全二叉树,所以我们可以计算出深度为6的最多结点个数,
n=2^6-1=63,根据题意完全二叉树的第六层有 8个叶子结点,所以我们可以判断,第六层可能为最后一层,或者为倒数第二层,即最后一层可能为第7层,然后我们再看题中为求最多节点个数,所以我们可以默认为有7层,
因为完全二叉树的第六层有 m=2^(6-1)=32 个结点,其中有8个叶子结点,其余都有儿子结点,因为要最多所以 k=(32-8)*2+63=111个结点。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值