【数据结构】二叉树的基本操作中的一些易错点
创始人
2024-05-28 22:16:49
0次

文章目录

  • 前言
  • 一、求二叉树节点个数
  • 二、求树的叶子结点个数
  • 三、求树的高度
  • 四、二叉树查找值为x的结点
  • 总结


前言

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


一、求二叉树节点个数

错误示例:

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;}}

总结

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

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...