0
点赞
收藏
分享

微信扫一扫

数据结构-->二叉树_OJ_02

各位老友!!欢迎来到本期博文!!今天,为大家讲解两道 二叉树(OJ)

1.对称二叉树

给定一个二叉树根结点 root, 检查是否轴对称

以下是情况分析  :>

数据结构-->二叉树_OJ_02_前序遍历二叉树

另外,不能忘记空结点的情况!!

那么代码如下 :>

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_02_判断镜像二叉树_02

以上较为难以理解的部分,如下 :>

数据结构-->二叉树_OJ_02_判断镜像二叉树_03

各位好友,上述“左边到左边”, “右边到右边”是啥意思?😊

------> 请注意,这是 判断二叉树是否为镜像树!从根结点往下,对于左子树的左边,同右子树的右边,进行比较

同理,另一个递归是 :> 从根结点往下, 左子树的右边, 同右子树的左边,进行比较!!

是不是这样说明,更容易理解呢! 本道 OJ 题已经讲解完成了!而下一道 OJ 题难度有所提升,请做好准备!!

2.二叉树 前序遍历

给定一颗二叉树的根结点 root, 返回该二叉树的前序遍历!!

前几期博文中,创建二叉树的过程,曾经实现过 前序遍历!然而,此处的前序遍历实现是放在了 OJ 上,有一定的硬性要求!!

对于本道 OJ 而言,需要返回一个数组长度!!说是数组长度,可能有些蒙圈,其实就是返还 结点总个数!

各位老友!!在这里,提到了数组,显然本道 OJ 题目的设计,就是要用数组来实现!!

下面,是官方给出的接口 :>

数据结构-->二叉树_OJ_02_判断镜像二叉树_04

是不是,同之前讲解过的二叉树前序遍历有很大的不同😊

但这里仍然用到之前学习过的前序遍历,只是,代码风格迥然有异!!

这就是知识的迁移运用能力!!哈😊 想念高三物理老师了!!

不过在这之前,先挖一坑!

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_02_数组_05

经过 OJ 测试,出现的结果,如下 :>

数据结构-->二叉树_OJ_02_前序遍历二叉树_06

那么对上述的结果,该如何改进和修改呢?这个时候,调试就派上了用场!!

为了更好的形象化描述,这种逻辑上的错误!!下面将展现递归过程 :>

数据结构-->二叉树_OJ_02_前序遍历二叉树_07

注意 蓝色框框的提示!当 i= 0 的时候,显然出现了BUG

数据结构-->二叉树_OJ_02_数组_08

这是由于,左右子树的 变量 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_02_数组_09

另外,还有一段代码,需要讲解一下!如下 : >

数据结构-->二叉树_OJ_02_数组_10

该段代码是何意思?

其实这种写法,是更加准确的,实现的效率,以及性能上会更好些!

毕竟,是用数组实现的,而开辟的空间刚刚好且将所有结点能存下,不会多,也不会少一点点儿!!

至此,本道 OJ 题就已经讲解完成了!难度上,相较于前一期,是有所提升的!不过,那种充实感是令人欣喜的😊


举报

相关推荐

0 条评论