链式结构二叉树的应用

概述

本文将对链式结构二叉树的几种功能进行实现与讲解

二叉树节点个数的判断

思路一:遍历二叉树

对于节点个数的判断,我们首先想到的最简单的方法就是任选一种遍历方式遍历二叉树(这里以前序遍历为例),定义变量size,每进行一次遍历就将size++,于是我们尝试写代码:

int TreeSize(BTNode* root)
{
	int size = 0;
	if (root == NULL)
		return 0;
	else
	{
		size++;
		TreeSize(root->left);
		TreeSize(root->right);
		return size;
	}
}

        我们尝试运行代码,却发现最后打印出的结果不为6,而是等于1。我们尝试分析一下代码,发现当每次对函数进行递归时,size都会被赋值0,size++后就为1,我们不想要size被每次都赋值为0,所以在这里我们将size设为静态变量(即在size前的int前加static),但仍然会出现问题,因为局部的静态变量只会被初始化一次,所以这个函数只能使用一次。运行结果如下:

        正确的实现方法:为了让size不会被每次都初始化为0,并且我们可以较方便地控制,我们应该将变量设为全局变量 (无论是否为静态变量),代码如下:

int size = 0;
int TreeSize(BTNode* root)
{
	if (root == NULL)
		return 0;
	else
	{
		size++;
		TreeSize(root->left);
		TreeSize(root->right);
		return size;
	}
}
//代码测试
int main()
{
	BTNode* root = CreatBinaryTree();
	size = 0;
	printf("TreeSize:%d\n", TreeSize(root));

	size = 0;
	printf("TreeSize:%d\n", TreeSize(root));

	size = 0;
	printf("TreeSize:%d\n", TreeSize(root));
	return 0;
}

测试结果:

思路二:前置递归

        我们不妨尝试一种新的思路:如果节点个数为0,则返回空,如果不为0,则在每个节点的位置进行:左子树+右子树+1的计算思路,以下图为例:

        先在1这个节点计算:1的左子树是2,2的节点数不知道,继续往下寻找,2的左子树是3,继续找,3的左子树是0,加上右子树0再加1等于1,所以三这个节点的值算出来等于1;再往上,2的左子树3的值1加右子树0再加1等于2;再往上1的左子树2的值为2加右子树4的值再加一,右子树4的值又继续往下寻找......最后得出来的值即为节点数。实现代码如下:

int TreeSize(BTNode* root)
{
	if (root == NULL)
		return 0;
	else
	{
		return TreeSize(root->left) + TreeSize(root->right) + 1;
	}
	//或者用三目操作符一步到位
	//return root == NULL?0:
	//	TreeSize(root->left) + TreeSize(root->right) + 1;
}

思路可能较为复杂,但转换成代码就十分简洁明了。

二叉树叶节点个数的判断

        在这里,我们首先尝试递归的思想:首先判空:节点为空返回0;如果某一节点的左右子树都为空,则返回1;如果至少有一个子树不为空,则直接返回该节点的左右子树相加的值(起到二叉树节点移动与将值存储起来的效果)。代码如下:

int TreeLeafSize(BTNode* root)
{
	if (root == NULL)
		return 0;

	if (root->left == NULL && root->right == NULL)
		return 1;

	return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}
//代码测试
int main()
{
	BTNode* root = CreatBinaryTree();
	printf("TreeLeafSize:%d\n", TreeLeafSize(root));
	return 0;
}

二叉树高度的判断

        我们想要求二叉树的高度,可以通过递归对二叉树的每一层进行比较,而每一次比较都会进行加1,实现代码如下:

int TreeHeight(BTNode* root)
{
	if (root == NULL)
		return 0;
	return TreeHeight(root->left) < TreeHeight(root->right) ? TreeHeight(root->right) + 1 :
		TreeHeight(root->left) + 1;
}

        但我们通过对递归的分析,会发现这样会出现大量内存的消耗,因为每次对节点进行计算后都没有存储计算所得值,这样就会导致越到后面计算多节点二叉树时前面都会再算一次,所以为了减少不必要的内存浪费,我们创造两个变量将左高度和右高度分别存储,代码如下:

int TreeHeight(BTNode* root)
{
	if (root == NULL)
		return 0;
	int LeftHeight = TreeHeight(root->left);
	int RightHeight = TreeHeight(root->right);
	return LeftHeight < RightHeight ? RightHeight + 1 :
		LeftHeight + 1;
}
//代码测试
int main()
{
	BTNode* root = CreatBinaryTree();
	printf("TreeHeight:%d\n", TreeHeight(root));
	return 0;
}

测试结果如下:

单值二叉树

思路一:递归实现

        首先为root判空:如果为空返回true,返回true的条件比较苛刻,所以我们倾向于返回false,因为只要有一个不相等就返回false,代码如下:

bool isUnivalTree(BTNode* root) 
{
	if (root == NULL)
		return true;
	if (root->left && root->left->data != root->data)
		return false;
	if (root->right && root->right->data != root->data)
		return false;
	return isUnivalTree(root->left)//根与左孩子比
		&& isUnivalTree(root->right);//根与右孩子比
}

思路二:遍历实现

通过再创建一个子函数,将原函数的值传入里面来进行每个节点数值的判断,代码如下:

bool _isUnivalTree(struct TreeNode* root,int val)
{
    if(root == NULL)
        return true;
    else if(val != root->val)
        return false;
    return _isUnivalTree(root->left,val)
        && _isUnivalTree(root->right,val);
}
bool isUnivalTree(struct TreeNode* root)
{
    return _isUnivalTree(root,root->val);
}

总结

在链表结构二叉树中,递归的使用是必不可少的,在使用的过程中,要时常问问自己:这个递归结构可不可以这样用?具体的逻辑实现过程是怎样的?只有这样,才能学好链表结构二叉树。

最后,如果觉得我写得不错,请别忘了点赞,收藏,评论!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值