前言

本期带来二叉树入门oj题的分享,写二叉树的题,最重要的就是分治思想

博主水平有限,不足错漏之处,望请斧正,感激不胜!

1. 单值二叉树

思路

每个结点值相等…

根 = 左子树 && 根 = 右子树,等量代换: a = b && b = c ==> a = c

所有只需要根 = 左子树 && 根 = 右子树,就满足单值二叉树

代码

bool isUnivalTree(struct TreeNode* root)
{if(root == NULL)return true;if(root->left != NULL && root->left->val != root->val)return false;if(root->right != NULL && root->right->val != root->val)return false;return isUnivalTree(root->left) && isUnivalTree(root->right);
}

代码分析:

  • 判断时,只判断能出结果的条件——不等则返回假,相等不用管,继续走
  • 还需要考虑结构:左/右子树不为空就比,为空肯定就不比了

2. 相同的树

思路

结构相同,结点值相等…

分:

  1. 判断值:根值等 && 左子树值等 && 右子树值等
  2. 判断结构:左子树为空时,右子树也为空

治:递归判断 根、左子树、右子树的值和结构

代码

bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{//前序遍历判断if(p == NULL && q == NULL)return true;if(p == NULL || q == NULL)return false;if(p->val != q->val)return false;return isSameTree(p->left, q->left)&& isSameTree(p->right,q->right);
}

代码分析:

  • 判断结构:

    • 两个都到空,满足结构相等
    • 只有一个到空,结构不等
  • 判断值
  • 满足pq的左子树相同 && pq的右子树相同

3.另一棵树的子树

思路

前序遍历,每次拿到的根传给 IsSameTree,判断相等

代码

bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{//前序遍历判断if(p == NULL && q == NULL)return true;if(p == NULL || q == NULL)return false;if(p->val != q->val)return false;return isSameTree(p->left, q->left)&& isSameTree(p->right,q->right);}bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot)
{if(root == NULL)return false;if(isSameTree(root, subRoot))return true;return isSubtree(root->left, subRoot)|| isSubtree(root->right, subRoot);
}

代码分析:

  • 这里的返回要求的不是两边都有子树了,而是找到一颗就够 —— 逻辑或

4. 翻转二叉树

思路

根的左右子树交换 ==> 左子树的左右子树交换,右子树的左右子树交换…

分:左右子树交换

治:递归交换左右子树

代码

struct TreeNode* invertTree(struct TreeNode* root)
{//递归交换左右子树if(root == NULL)return NULL;struct TreeNode* tmp = root->left;root->left = root->right;root->right = tmp;invertTree(root->left);invertTree(root->right);return root;
}

代码分析:

  • 即使左右子树交换了也不影响后续的交换:交换只在本根结点的子树内,和兄弟结点的子树互不影响

5.对称二叉树

思路

根结点没有对称可言,所以对称的判断从根结点的左右子树开始

如何判断对称?假设我们拿到图中 左2 和 右2:

  1. 判断他俩的值和结构
  2. 判断 左2 的左子树和 右2 的右子树 ,再判断 左2 的右子树和 右2 的左子树

分:判断根结点和子树

治:递归判断 左的左和 右的右 && 左的右 和 右的左

代码

bool Compare(struct TreeNode* left, struct TreeNode* right)
{if(left == NULL && right == NULL)return true;//比结构if(left == NULL || right == NULL)return false;//比值if(left->val != right->val)return false;//左的左 比 右的右//左的右 比 右的左return Compare(left->left, right->right)&& Compare(left->right, right->left);}bool isSymmetric(struct TreeNode* root)
{return Compare(root, root);
}

代码分析:

  • 比值和结构和翻转二叉树类似
  • 初始状态直接传root和root,而后递归 左的左和 右的右 && 左的右 和 右的左

6.平衡二叉树

思路

abs(左子树高度 - 右子树高度) >= 1,递归判断每棵子树

代码

int TreeHeight(struct TreeNode* root)
{if(root == NULL)return 0;    int lh = TreeHeight(root->left);int rh = TreeHeight(root->right);return lh > rh ? lh+1 : rh+1;
}bool isBalanced(struct TreeNode* root)
{if(root == NULL)return true;//每个根的左右高度绝对值 <=1if(abs(TreeHeight(root->left) - TreeHeight(root->right)) > 1)return false;return isBalanced(root->left)&& isBalanced(root->right);
}

代码分析:

  • 求树的高度再上一篇博客实现过
  • 要求左右都满足平衡——逻辑与

7.二叉树的前序遍历

思路

前序遍历没什么问题,只不过这道题的接口要求我们把每个结点值放进数组

代码

int TreeSize(struct TreeNode* root)
{if(root == NULL)return 0;return TreeSize(root->left)+ TreeSize(root->right)+ 1;
}void PreOrder(struct TreeNode* root, int* arr, int* pi)
{//遍历,并放到数组内if(root == NULL)return;//root ==> left ==> rightarr[*pi] = root->val;(*pi)++;PreOrder(root->left, arr, pi);PreOrder(root->right, arr, pi);}int* preorderTraversal(struct TreeNode* root, int* returnSize)
{int n = TreeSize(root);int* arr = (int*)malloc(sizeof(int) * n);*returnSize = n;int i = 0;PreOrder(root, arr, &i);return arr;
}

代码分析

  • 和之前实现的前序遍历,区别仅在“输出”
  • 中序后序同理

8.二叉树遍历

思路

输入的字符串为前序遍历字符串,根据它来建树就是:根 ==> 左 ==> 右,每次拿到新的一个字符放进根,再递归左子树右子树

最后中序遍历输出即可

代码

#include <stdio.h>
#include <stdlib.h>
typedef char BTDataType;
typedef struct BTNode
{BTDataType val;struct BTNode* left;struct BTNode* right;
}BTNode;BTNode* BuildTree(char* s, int* pi)
{if(s[*pi] == '#'){(*pi)++;return NULL;}BTNode* root = (BTNode*)malloc(sizeof(BTNode));root->val = s[(*pi)++];root->left = BuildTree(s, pi);root->right = BuildTree(s, pi);return root;
}void InOrder(BTNode* root)
{if(root == NULL)return;InOrder(root->left);printf("%c ", root->val);InOrder(root->right);
}int main()
{char s[101];scanf("%s", s);int i = 0;BTNode* root = BuildTree(s, &i);InOrder(root);
}

代码分析

  • 访问字符串需要留意,这里我们用 数组名+下标 的方式访问字符串

    • 下标在传参时传地址(每次用完一个字符往下走,需要改变下标的值)

今天的分享就到这啦,这里是培根的blog,期待与你共同进步!

【数据结构初阶-oj】入门二叉树的入门oj相关推荐

  1. 数据结构初阶——链式二叉树

    目录 树概念及结构 树的概念 树的表示 二叉树概念及结构 概念 特殊二叉树 二叉树的性质 二叉树链式结构及实现 二叉树的简单创建 二叉树的前序遍历 二叉树中序遍历与二叉树后序遍历 求二叉树节点个数 求 ...

  2. 数据结构初阶(4)(OJ练习【判断链表中是否有环、返回链表入口点、删除链表中的所有重复出现的元素】、双向链表LinkedList【注意事项、构造方法、常用方法、模拟实现、遍历方法、顺序表和链表的区别)

    接上次博客:数据结构初阶(3)(链表:链表的基本概念.链表的类型.单向不带头非循环链表的实现.链表的相关OJ练习.链表的优缺点 )_di-Dora的博客-CSDN博客 目录 OJ练习 双向链表--Li ...

  3. 数据结构初阶最终章------>经典八大排序(C语言实现)

    前言:   正如标题所言,本篇博客是数据结构初阶的最终章节.但不是数据结构的最终章节!事实上,诸如AVL 树,红黑树这样高阶复杂的数据结构使用C语言非常麻烦,这些数据结构我会放在后续的C++的博客中去 ...

  4. 二叉树前中后序遍历+刷题【中】【数据结构/初阶/C语言实现】

    文章目录 1. 二叉树基础操作 1.1 二叉树遍历 1.1.1 前序遍历 前序遍历(Pre-Order Traversal) 1.1.2 中序遍历 中序遍历(In-Order Traversal) 1 ...

  5. 【数据结构初阶】链表(下)——带头双向循环链表的实现

    目录 带头双向循环链表的实现 1.带头双向循环链表的节点类型 2.创建带头双向循环链表的节点 3.向带头双向循环链表中插入数据 <3.1>从链表尾部插入数据 <3.2>从链表头 ...

  6. 数据结构初阶:二叉树

    二叉树 链表和数组都是线性结构,而树是非线性的结构. 树是依靠分支关系定义出的一种层次结构.社会亲缘关系和组织结构图都可以用树来形象地表示. 1. 树 1.1 树的定义 树是 n ( n ≥ 0 ) ...

  7. 树与二叉树(二叉树前传、数据结构初阶、C语言)

    文章目录 前言 一.树的概念及结构 (一).树的概念 (二).树的相关概念 (三).树的表示 二.二叉树的概念及结构 (一).二叉树的概念 (二).满二叉树和完全二叉树 (三).二叉树的性质 (四). ...

  8. 数据结构初阶之二叉树——概念篇

    目录 一. 树的概念及结构 1. 树的概念 2. 树的相关概念 3. 树的表示 4. 实际运用 二. 二叉树概念及结构 1. 概念 2. 完全二叉树和满二叉树 3. 二叉树的性质 三. 练习 四. 练 ...

  9. 【数据结构初阶】第八篇——二叉树的链式结构(二叉树的前、中和后序遍历+层序遍历+链式结构的实现+相关简单的递归问题)

    ⭐️本篇博客我要来和大家一起聊一聊数据结构中的二叉树的链式结构的实现及相关的一些问题的介绍 ⭐️博客代码已上传至gitee:https://gitee.com/byte-binxin/data-str ...

  10. 【C++初阶】一、C++入门基础(详细总结)

    文章目录 一.什么是C++ 二.C++关键字(C++98) 三.命名空间 3.1命名空间定义 1.命名空间的普通定义 2.命名空间可以嵌套定义 3. 同一个工程中允许存在多个相同名称的命名空间,编译器 ...

最新文章

  1. Emotion英语学习
  2. lighttpd+PHP上传文件
  3. 【Paper】2018_多无人机协同编队控制算法研究_林倩玉
  4. 当 TiDB 与 Flink 相结合:高效、易用的实时数仓
  5. 最新Golang安装教程(Linux环境 Ubuntu + Go) 附centos安装视频链接
  6. LeetCode 303,560,1248 (前缀求和 )
  7. 数学发展重在人才,丘成桐鼓励年轻学子“无法无天”
  8. 面试时会谈薪的人一开口就赢了:让你薪资翻倍的谈薪技巧
  9. 不安装oracle使用exp命令
  10. JMeter中持续时间设置成永远调度器才会起作用
  11. 从编程小白到全栈开发:服务的调用
  12. Android版本历史变迁
  13. anaconda下jupyter无法自动打开网页
  14. 大三下,我们该做什么?一篇被转万次的日志,你值得一看
  15. 莫纳什大学计算机专业排名,2020年莫纳什大学排名前五的专业有哪些
  16. 超级可爱的萌妹焊接艺术壁画,它是画上去的!
  17. 关于app store distribution出现的'armv7'与最小版本'3.0'不兼容的问题
  18. 流程引擎动态任务实现(收发文流程案例)
  19. 【IT项目管理】第10章 习题
  20. 使用echarts,制作色温图

热门文章

  1. CentOS更换阿里yum源
  2. java如何解除文件锁定状态_Eclipse操作SVN时中断锁定,文件的解锁方法
  3. java 上位机_java实现上位机与下位机串口通信
  4. 统计学中sp_统计学中pssp是什么意思
  5. HTTP错误代码大全,http网站状态码各代表了什么?
  6. 开源软件漏洞安全风险分析
  7. python编写群发软件编写_我帮公司财务写了个“群发工资条”的 Python 脚本!
  8. php 聊天室设计,基于PHP+MySQL的聊天室设计_PHP教程
  9. 2021新手、小白快速安装KALI教程
  10. 华为交换机,登录密码忘记