各位老友!!欢迎来到本期博文!!今天,为大家讲解两道 二叉树(OJ)
1.对称二叉树
给定一个二叉树根结点 root, 检查是否轴对称
以下是情况分析 :>
另外,不能忘记空结点的情况!!
那么代码如下 :>
typedef int BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
bool _isSymmetric(BTNode* left, BTNode* right)
{
if(left == NULL && right == NULL)
{
return false;
}
if(left == NULL && right == NULL)
{
return false;
}
if(left ->data != right ->data)
{
return false;
}
return _isSymmetric(left ->left, right ->right)
&& _isSymmetric(left ->right, right ->left);
}
bool isSymmetric(BTNode* root)
{
if(root == NULL)
{
return true;
}
_isSymmetric(root ->left, root ->right);
}
为了更好的观感体验,特此附上有色彩的代码图样 :>
以上较为难以理解的部分,如下 :>
各位好友,上述“左边到左边”, “右边到右边”是啥意思?😊
------> 请注意,这是 判断二叉树是否为镜像树!从根结点往下,对于左子树的左边,同右子树的右边,进行比较
同理,另一个递归是 :> 从根结点往下, 左子树的右边, 同右子树的左边,进行比较!!
是不是这样说明,更容易理解呢! 本道 OJ 题已经讲解完成了!而下一道 OJ 题难度有所提升,请做好准备!!
2.二叉树 前序遍历
给定一颗二叉树的根结点 root, 返回该二叉树的前序遍历!!
前几期博文中,创建二叉树的过程,曾经实现过 前序遍历!然而,此处的前序遍历实现是放在了 OJ 上,有一定的硬性要求!!
对于本道 OJ 而言,需要返回一个数组长度!!说是数组长度,可能有些蒙圈,其实就是返还 结点总个数!
各位老友!!在这里,提到了数组,显然本道 OJ 题目的设计,就是要用数组来实现!!
下面,是官方给出的接口 :>
是不是,同之前讲解过的二叉树前序遍历有很大的不同😊
但这里仍然用到之前学习过的前序遍历,只是,代码风格迥然有异!!
这就是知识的迁移运用能力!!哈😊 想念高三物理老师了!!
不过在这之前,先挖一坑!
typedef int BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
//求结点总个数
int BTSize(BTNode* root)
{
if(root == NULL)
{
rturn 0;
}
return BTSize(root ->left) + BTSize(root ->right) + 1;
}
//前序遍历
void PreNode(BTNode* root, int* a, int i)
{
if(root == NULL)
{
return ;
}
a[i++] = root ->data;
PreNode(root ->left, a, i);
PreNode(root ->right, a, i);
}
//不一样的前序遍历
int* PreoderTraversal(BTNode* root, int* returnSize)
{
*returnSize = BTSize(root);
int* a = (int*)malloc(sizeof(int) * (*returnSize)); // 稍后进行讲解
int i = 0;
PreNode(root, a, 0);
return a;
}
为了更好的观感体验,特此附上有色彩的代码图样 :>
经过 OJ 测试,出现的结果,如下 :>
那么对上述的结果,该如何改进和修改呢?这个时候,调试就派上了用场!!
为了更好的形象化描述,这种逻辑上的错误!!下面将展现递归过程 :>
注意 蓝色框框的提示!当 i= 0 的时候,显然出现了BUG
这是由于,左右子树的 变量 i 作为局部变量。当完成 左子树的遍历的时候,经返还,也就是出了左子树的栈区,自动销毁了!!接下来再入右子树的栈区,显然变量 i 是从 0 开始的!!因此,我们不愿意 让 i 出栈后自动销毁,想当然,就需要用到传值操作了!
那么,正确代码如下 :>
typedef int BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
//求结点总个数
int BTSize(BTNode* root)
{
if(root == NULL)
{
rturn 0;
}
return BTSize(root ->left) + BTSize(root ->right) + 1;
}
//前序遍历
void PreNode(BTNode* root, int* a, int* pi)
{
if(root == NULL)
{
return ;
}
a[(*pi)++] = root ->data;
PreNode(root ->left, a, pi);
PreNode(root ->right, a, pi);
}
//不一样的前序遍历
int* PreoderTraversal(BTNode* root, int* returnSize)
{
*returnSize = BTSize(root);
int* a = (int*)malloc(sizeof(int) * (*returnSize)); // 稍后进行讲解
int i = 0;
PreNode(root, a, &i);
return a;
}
为了更好的观感体验,特此附上有色彩的代码图样 :>
另外,还有一段代码,需要讲解一下!如下 : >
该段代码是何意思?
其实这种写法,是更加准确的,实现的效率,以及性能上会更好些!
毕竟,是用数组实现的,而开辟的空间刚刚好且将所有结点能存下,不会多,也不会少一点点儿!!
至此,本道 OJ 题就已经讲解完成了!难度上,相较于前一期,是有所提升的!不过,那种充实感是令人欣喜的😊