【数据结构】二叉树的基本操作中的一些易错点


前言

笔者整理出了一些关于萌新在入门二叉树时容易犯的一些错误,你也来试试自己会不会掉到这些坑里把~


一、求二叉树节点个数

错误示例:

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

这里的错误是,每当递归一次时,其实是在函数栈帧中另外开辟了一个变量size,每次size++都是在新开辟的变量size上++。并没有影响到最开始的变量size。

正确示例:

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

在这个示例中,size将在静态区开辟,并且只会初始化一次,不用担心每次递归时会将size重新初始化为0。这样,size每次都可以正确的+1;
另外的方法就是,创建一个全局变量,并将整型变量的地址传入函数,通过变量的地址改变变量的大小。但是这样需要注意的是,需要每次要计数的时候手动将全局变量置为0。

二、求树的叶子结点个数

错误示例:

int TreeLeafSize(BTNode* root)
{
	if(root->left == NULL&&root->right == NULL)
		{
			return 1;
		}
	return TreeLeafSize(root->left)+TreeLeafSize(root->right);
}

那么这里错在哪呢?
其实这里错在缺少一个前置判断

if(root == NULL)
{
	return 0;
}

如果没有这个判断条件的话,就会出现访问空指针的情况。

三、求树的高度

错误示例:

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

这段代码逻辑上没有错,但是其中有一个非常大的诟病。当函数在递归时,会反复调用TreeHeight()。因为之前的调用没有将结果记下来,就导致每当需要上一次函数调用的结果时,又再次去调用函数。
改进:

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

四、二叉树查找值为x的结点

错误示例:

BTNode* TreeFind(BTNode* root,BTDataType x)
{
	if(root == NULL)
		return NULL;
	if(root->data == x)
	{
		return root;
	}
	TreeFind(root->left,x);
	TreeFind(root->right,x);
}

这段代码逻辑看起来非常的自洽,但事实上逻辑上并不自洽。 首先要问自己一个问题:最下面的两次TreeFind的目的是什么?
事实上最下面两次TreeFind没有任何作用,因为你没有用到TreeFind的结果。

正确代码:

BTNode* TreeFind(BTNode* root,BtDataType x)
{
	if(root == NULL)
	{
		return NULL;
	}
	if(root->data == x)
	{
		return root;
	}
	BTNode* ret1 = TreeFind(root->left,x);
	if(ret1)
	{
		return ret1;
	}
	BTNode* ret2 = TreeFind(root->left,x);
	if(ret2)
	{
		return ret2;
	}
	
}

总结

以上就是笔者对二叉树递归里的一些易错点的记录。代码纯手打,可能存在漏洞、瑕疵。如发现欢迎指正!

  • 20
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论
二叉树是一种重要的数据结构,由于其特殊的结构和性质,需要具备一些基本的操作来对二叉树进行处理。 首先是创建二叉树。可以通过读取用户输入或者其他方式来构建一个二叉树。创建二叉树的过程可以使用递归的方式,通过不断地输入节的值和连接关系来构造二叉树。 其次是遍历二叉树。常见的遍历方式有前序遍历、序遍历和后序遍历。前序遍历先访问根节,然后遍历左子树和右子树;序遍历按照左子树、根节和右子树的顺序遍历;后序遍历先遍历左子树和右子树,最后访问根节。通过递归的方式,可以实现这三种遍历方式。 另外一个常用的操作是查找二叉树的节。可以通过比较节的值,逐层搜索二叉树,找到目标节。如果目标节不存在,可以返回一个特定的值来表示找不到。 还有一个重要的操作是插入节。可以通过比较节的值,找到插入的位置。如果待插入的节小于当前节,就插入到左子树;如果待插入的节大于当前节,就插入到右子树。插入节后,需要调整二叉树的结构,保持二叉树的性质。 最后,删除节也是一个常见的操作。删除节时,需要考虑节的左右子树。可以通过将节的左子树的最大节或者右子树的最小节上移来替代被删除的节。删除节后,同样需要调整二叉树的结构,保持二叉树的性质。 这些是二叉树基本操作,它们在实际应用有广泛的应用,比如在搜索、排序和图等领域。掌握这些操作,可以更好地理解和应用二叉树

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dontflinch

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值