网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
同学们不懂的地方一定要画图
去理解!!
🎄3. 中序遍历
中遍历结果为:H D I B E J A F K C G
1️⃣ 动画演示:👇🏻
2️⃣代码实现💡:
void InOrder(BTNode\* root)
{
if (root == NULL)// 递归中遇到NULL,返回上一层节点
{
printf("# ");
return;
}
InOrder(root->left);// 递归遍历左子树
printf("%d ", root->data);
InOrder(root->right);// 递归遍历右子树
}
❗递归展开图(以下图为例):
画图很重要,不理解就要去画图✅
还是刚刚的递归图,只是改变了访问顺序,中序:左子树——根——右子树
🌍此处的递归结果:# 3 # 2 # 1 # 5 # 4 # 6 #
🎄4. 后序遍历
1️⃣ 动画演示:👇🏻
2️⃣代码实现💡:
void PostOrder(BTNode\* root)
{
if (root == NULL)// 递归中遇到NULL,返回上一层节点
{
printf("# ");
return;
}
PostOrder(root->left);// 递归遍历左子树
PostOrder(root->right);// 递归遍历右子树
printf("%d ", root->data);
}
❗递归展开图(还是以下图为例):
还是要去画递归展开图,只是改变了访问顺序,后序:左子树——右子树——根
🌍此处的递归结果:# # 3 # 2 # # 5 # # 6 4 1
ps:递归展开图多画就能理解,才方便后序更难的二叉树。
🎄5. 层序遍历
1️⃣ 演示:👇🏻
2️⃣🎇思路讲解:
- 借助一个队列实现:先进先出
- 上一层带下一层,先进去的先出,每次循环出一个
3️⃣代码实现💡:
void LevelOrder(BTNode\* root)
{
Quene q;
QueneInit(&q);
if (root)
{
QuenePush(&q, root);
}
while (!QueneEmpty(&q))
{
BTNode\* front = QueneFront(&q);
printf("%d ", front->data);
QuenePop(&q);
if (front->left)
{
QuenePush(&q, front->left);
}
if (front->right)
{
QuenePush(&q, front->right);
}
}
printf("\n");
QueneDestroy(&q);
}
完全一样
🐾探究二叉树节点个数以及高度
🎄1.二叉树节点个数
定义一个Count,计算结点的个数,那么Count是全局变量还是局部变量?
答案:全局变量!不然每次递归各自加各自的Count,无意义。
💡代码实现:遍历法
//遍历
int count = 0;
void BinaryTreeSize1(BTNode\* root)
{
if (root == NULL)
{
return;
}
++count;
BinaryTreeSize1(root->left);
BinaryTreeSize1(root->right);//此处为前序,其实前中后序都是可以的
}
同一棵树在我第两次调用的时候,发现第二次的结果不同于第一次
📌很简单,第二次是在第一次调用的基础上累加的。所以最好的方式是:
每次调用之前,都给count初始化为0
到这里大家是不是以为已经解决了?其实这里还有个大问题:linux中的多线程
如果这个函数被多线程去调用就会出错,也就是并发
,两个线程都调用这个函数,会加在同一个count上,也就出错了。
那有没有更好的方法呢❓ 答案肯定是有的✅
💡代码实现:分治思路
//分治思想
int BinaryTreeSize2(BTNode\* root)
{
return root == NULL ? 0 : BinaryTreeSize2(root->left) + BinaryTreeSize2(root->right) + 1;
}
如果大家对这个方法不熟悉,可以画一下栈帧展开图🙌
🎄2. 二叉树叶子节点个数
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);
}
这个理解起来还可以吧🤏拿捏~
🎄3. 二叉树第k层节点个数
大家看到k层是不是想到了层序遍历呢?
但这和层序遍历没有关系,还是要用
子问题
的思维去解题~转化成:
- 求左子树的第k-1层+求右子树的第k-1层
💡代码实现
int TreeKLevel(BTNode\* root, int k)
{
assert(root);
if (root == NULL)
return 0;
if (k == 1)
return 1;
return TreeKLevel(root->left,k-1) + TreeKLevel(root->right,k-1);
}
ps:注意递归的时候只能用
k-1
而不是 k–
- 因为递归到时候,递归了左子树,之后还要递归右子树,若使用了k–,递归左树的时候k已经自减减少了,再回来求右树时候的k已经是错的k了,所以要保证k不能变
🎄4. 二叉树查找值为x的结点
第一次写:(错误写法)
BTNode\* BinaryTreeFind(BTNode\* root, BTDataType x)
{
if (root->data == x)
return root;
if (root == NULL)
return NULL;
if (BinaryTreeFind(root->left, x))
return BinaryTreeFind(root->left, x);
if (BinaryTreeFind(root->right, x))
return BinaryTreeFind(root->right, x);
return NULL;
}
这种写法,我们发现如果我们找到了结点,返回值的时候还要再递归一次,太费劲了
好比我们写博客,写到一半,电脑死机了,还要重新写的感觉😈
💡代码实现(最好的方式💯)
BTNode\* BinaryTreeFind(BTNode\* root, BTDataType x)
{
if (root == NULL)
return NULL;
if (root->data == x)
return root;
BTNode\* left = BinaryTreeFind(root->left, x);
if (left)
return left;
BTNode\* right = BinaryTreeFind(root->right, x);
if (right)
return right;//每一次return都是回到上一层
return NULL;
}
🎄5.求二叉树的高度
二叉树的深度改怎么样求呢?
一样利用分治的思想来实现
- 左右分别递归,返回上一层加1,再比较左右树高度
🎇思路讲解:
💡代码实现
int TreeDepth(BTNode\* root)
{
if (root == NULL)
return 0;
int leftDepth = TreeDepth(root->left);
int RightDepth = TreeDepth(root->right);
return leftDepth > RightDepth ? leftDepth+1 : RightDepth+1;
}
🎄6.销毁二叉树
销毁用什么序列呢?
后序!
- 若使用前序遍历的话,删除了节点还能找到左右子树么?
- 可以是可以,但还要指针保存起来,比较麻烦
💡代码实现
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
RightDepth+1;
}
### 🎄6.销毁二叉树
销毁用什么序列呢?
>
> **后序!**
>
>
>
* 若使用前序遍历的话,删除了节点还能找到左右子树么?
* 可以是可以,但还要指针保存起来,比较麻烦
💡**代码实现**
[外链图片转存中...(img-v3I2F2JN-1715776740206)]
[外链图片转存中...(img-gDYnw0U4-1715776740207)]
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**