二叉树经典例题

前言:

本文主要讲解了关于二叉树的简单经典的例题。

因为二叉树的特性,所以关于二叉树的大部分题目,需要利用分治的思想去递归解决问题。

分治思想:

把大问题化简成小问题(根节点、左子树、右子树),返回条件就是最小规模的子问题

一、二叉树中结点的个数

思路:

采用分而治之的思想, 先访问左子树,再访问右子树,然后再加上自己的个数也就是1。

原码:

//采用分治的思想去解决
int TreeSize(BTNode* root)
{return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;/*if (root == NULL)return 0;else{return TreeSize(root->left) + TreeSize(root->right) + 1;}*/
}

二、二叉树中叶子结点的个数

思路:

分为三个判断条件。

  1. 如果是空结点,就返回0
  2. 如果是叶子结点就返回1
  3. 不满足上述两种情况,就继续访问左子树+右子树 

原码:

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

三、求第k层的结点个数

思路:

当前树的第k层 = 左子树的k-1层 + 右子树的k-1层,以此类推

当k == 1时,如果不为空结点,就返回1,如果是空结点就返回0。

原码:

int TreeKLevel(BTNode* root, int k)
{assert(k > 0);if (root == NULL)return 0;if (k == 1){return 1;}return TreeKLevel(root->left, k - 1)+ TreeKLevel(root->right, k - 1);
}

四、判断单值二叉树

965. 单值二叉树

思路:

首先明确等号具有传递性,只要根节点和右节点相等,然后根节点与左结点相等,就说明这颗小树就是单值。

并且这是前序遍历,先遍历根节点,如果根节点不是单值二叉树,那么就没有必要去遍历后面的。

这点可以利用&&与操作符实现,与操作符的特性是只要前者是假,后面就不会执行

原码:

bool isUnivalTree(struct TreeNode* root){//采用前序的思想//利用等于号的传递性if(root == NULL)return true;//跟左节点比较    if(root->left){if(root->val != root->left->val)return false;}//跟右结点比较if(root->right){if(root->val != root->right->val)return false;}return isUnivalTree(root->left) && isUnivalTree(root->right);
}

五、销毁二叉树

思路:

采用后序遍历,防止先销毁根节点,导致左右节点找不到了

原码:

void DestroryTree(BTNode* root)
{//递归必须要有判断条件if (root == NULL)return;//需要后序遍历,不然先销毁根节点,左右子树就找不到了DestroryTree(root->left);DestroryTree(root->right);free(root);root = NULL;

六、在二叉树中根据值搜索结点

思路:

可以直接采取前序遍历,

  1. 最小子问题就是当结点为空时返回空
  2. 结点的值就是寻找的值就返回该节点
  3. 不满足上述条件,就继续递归遍历,先左子树再右子树,如果左子树已经找到结点,直接返回

原码:

BTNode* TreeFind(BTNode* root, int x)
{if (root == NULL)return NULL;if (root->val == x)return root;BTNode* ret = TreeFind(root->left, x);if (ret != NULL)return ret;return TreeFind(root->right, x);
}

七、检查两颗树是否相同

100. 相同的树

思路:

采用分治的思想,把问题逐步缩小,最小子问题就是两个结点是否相同

  1. 我们首先要清楚是不是空树
  2. 然后如果一个为空,另一个不为空
  3. 当结点都存在时,再判断结点的值是否相等

原码:

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

八、对称二叉树

​​​​​​101. 对称二叉树

思路;

本题跟上一题两颗二叉树是否相同非常相似,只需要将比较的结点改变顺序,因为是对称,所以左节点要跟右节点相等。

原码:

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->right) && isSameTree(p->right,q->left);
}bool isSymmetric(struct TreeNode* root){return isSameTree(root->left,root->right);
}

九、另一棵树的子树

572. 另一棵树的子树

思路:

这道题也是判断相同树的衍生题目,当根节点与subTree的根节点相同时,可以判断两颗树是否相同,并利用||来判断。

原码:

bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){//防止递归到空结点,造成非法访问if(root == NULL)return false;//相同前提是根节点要一致if(root->val == subRoot->val){if(isSameTree(root,subRoot))return true;}//只要发现相同,没有必要进行下面的比较,所以是||return isSubtree(root->left,subRoot) || isSubtree(root->right,subRoot);
}

十、二叉树的最大深度

104. 二叉树的最大深度

思路:

我们分别求出左子树和右子树的深度,再返回较大的值。

注意:

我们不能将代码写成上面的形式,首先定位上面的代码是非常差的代码,返回值返回的时候会重新进入函数计算,并且是每一个结点!因此我们需要提前将返回值保存起来,将值进行比较去返回。

原码:

int maxDepth(struct TreeNode* root){if(root == NULL)return 0;int leftmax = maxDepth(root->left) + 1;int rightmax = maxDepth(root->right) + 1;return leftmax > rightmax ? leftmax : rightmax;
}

十一、二叉树的前序遍历

​​​​​​144. 二叉树的前序遍历

思路:

本题并不是简单的递归求解,需要根据题目要求,因为我们用C语言进行求解。

  1. 数组的大小需要我们先自己求这颗树的结点大小,单独开辟一个函数去求解
  2. 我们不能递归自己的函数,因为每次递归都需要动态开辟一个新的数组,因此还需要重新创建一个函数去解决
  3. 注意新的函数中数组下标i的值需要传地址,因为递归过程中有很多i,直接传地址

原码:

//先提前算好二叉树结点的个数,便于开辟动态数组的大小
int TreeSize(struct TreeNode* root)
{return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}void preorder(struct TreeNode* root,int* arr,int* i)//传数组下标的地址,避免使用全局变量的麻烦
{if(root == NULL){return;}arr[(*i)] = root->val;(*i)++;preorder(root->left,arr,i);preorder(root->right,arr,i);
}int* preorderTraversal(struct TreeNode* root, int* returnSize){*returnSize = TreeSize(root);int *arr = (int*)malloc(sizeof(int)*(*returnSize));//需要再创建一个函数用来递归,不然每次调用该函数进行递归都会动态开辟int i = 0;preorder(root,arr,&i);return arr;
}

十二、通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树

注意:

*pi++  (*pi)++两者含义不同,为了避免优先级的问题,我们直接加上括号!

原码:

BTNode* BinaryTreeCreate(char* str, int* pi)
{if (str[*pi] == '#'){(*pi)++;return NULL;}BTNode* root = (BTNode*)malloc(sizeof(BTNode) * 1);root->val = str[*pi];(*pi)++;root->left = BinaryTreeCreate(str, pi);root->right = BinaryTreeCreate(str, pi);return root;
}

十三、二叉树的层序遍历

涉及到层序遍历,大部分情况下需要借助队列进行求解。

思路:

上一层带下一层,先进先出。

原码:

十四、判断是否是完全二叉树

思路:

利用层序遍历,如果非空结点是连续的,就是完全二叉树。

如果非空结点是不连续的,中间有空结点,就是非完全二叉树。

原码:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/95138.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetCode 53.最大子数和 图解 + 贪心算法/动态规划+优化

53. 最大子数组和 - 力扣(LeetCode) 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组 是数组中的一个连续部分。 示例 1: 输入…

VUE3照本宣科——路由与状态管理器

VUE3照本宣科——路由与状态管理器 前言一、路由(router)1.createRouter2.router-link3.router-view4.useRoute5.useRouter6.路由守卫7.嵌套路由 二、状态管理器(Pinia)1.定义Store(1)Option Store&#x…

电气走线——部件、线缆、线号、端子排

目录 1.部件 2.线缆 3.端子排 1.部件 元器件选型 2.线缆 3.端子排

【在凸多边形的图像中查找顶点】估计具有已知顶点数的像素化凸多边形角点研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

SpringCache--缓存框架 ----苍穹外卖day7

目录 简介 ​快速入门 引入依赖 常用注解​ 使用步骤 1.开启缓存注解 2. Cacheable注解 简介 快速入门 引入依赖 常用注解 使用步骤 1.开启缓存注解 2. Cacheable注解 该注解仅用于查询操作&#xff0c…

深度学习(3)---PyTorch中的张量

文章目录 一、张量简介与创建1.1 简介1.2 张量的创建 二、张量的操作2.1 张量的拼接与切分2.2 张量索引 三、张量的数学运算 一、张量简介与创建 1.1 简介 1. 张量是一个多维数组,它是标量、向量、矩阵的高维拓展。 2. 在张量的定义中,方括号用于表示张…

1.3 数据库系统的结构

前言: **前言笔记:数据库系统的结构层次与角度** --- **1. 数据库系统的结构考察**: - 可以从多种层次和不同角度来考察。 - 结构的选择取决于我们查看数据库的角度。 --- **2. 从** **开发人员** **的角度**: - **…

堆--数组中第K大元素

如果对于堆不是太认识&#xff0c;请点击&#xff1a;堆的初步认识-CSDN博客 解题思路&#xff1a; /*** <h3>求数组中第 K 大的元素</h3>* <p>* 解体思路* <ol>* 1.向小顶堆放入前k个元素* 2.剩余元素* 若 < 堆顶元素, 则略过* …

1800_vim的宏录制功能尝试

全部学习信息汇总&#xff1a; GreyZhang/editors_skills: Summary for some common editor skills I used. (github.com) 最近5年多来&#xff0c;我emacs的编辑器用的还是比较多的。我的配置基本上是一个spacemacs&#xff0c;然后根据自己的需求增加了一丁点儿的其他配置。而…

Spring的AOP开发-基于xml配置的AOP

基于xml配置的AOP xml方式AOP快速入门 在前面我们自己编写的AOP基础代码还存在一些问题&#xff0c;主要是 被增强的范围写死了通知对象的方法在代码中写死了具体文章传送:Spring的AOP开发-AOP简介-CSDN博客 我们可以通过配置文件解决上述问题 配置增强的范围&#xff08;配…

玩转Linux—如何在Linux环境中部署MySQL、Redis和nginx

1、Linux常用命令 Linux学习之路&#xff1a; VMware虚拟机安装Linux系统(详解版) 查看当前文件目录&#xff1a;ls查看目录中文件详细信息&#xff1a;ll输出当前所处的目文件目录&#xff1a;pwdLinux查看当前IP地址&#xff1a;ifconfigWindows查看当前IP地址&#xff1…

想要精通算法和SQL的成长之路 - 岛屿数量和岛屿的最大面积

想要精通算法和SQL的成长之路 - 岛屿数量和岛屿的最大面积 前言一. 岛屿数量1.1 并查集数据结构构造1.2 使用并查集编码 二. 岛屿的最大面积 前言 想要精通算法和SQL的成长之路 - 系列导航 并查集的运用 一. 岛屿数量 原题链接 从这个题目的特性来看&#xff0c;它适合用并查集…

用Python操作PPT的办公自动化教程

PPT通过其精美的可视化技巧以及良好的演示效果&#xff0c;成为了职场人士的必备技能。PPT的设计是一门大学问&#xff0c;无论是设计技巧&#xff0c;还是操作方法&#xff0c;都衍生出了专门的课程。 主要介绍Python操作PPT的技巧&#xff0c;编程的优势在于处理速度&#x…

10分钟了解数据架构、数据模型

写在前面&#xff1a;很多小伙伴分不清数据架构与数据模型&#xff0c;同时如何做好数据建模也有一定的疑问 1. 数据架构、数据模型、数据建模区别与联系 企业架构包含业务架构、数据架构、应用架构和技术架构。数据架构的主要目标是有效的管理数据&#xff0c;以及有效地管理…

(三) gitblit管理员手册

(一)gitblit安装教程 (二) gitblit用户使用教程 (三) gitblit管理员手册 目录 权限管理创建仓库时创建用户普通用户 管理员用户访问限制和访问权限仓库创建权限分配 Teams普通组管理员组 参考资料 权限管理 创建仓库时 选择指定的人员查看,克隆,推送 不允许fork 对应Anonymo…

十、2023.10.4.计算机网络(one).10

文章目录 1、简述静态路由和动态路由&#xff1f;2、说说有哪些路由协议&#xff0c;都是如何更新的&#xff1f;3、简述域名解析过程&#xff0c;本机如何干预域名解析&#xff1f;4、简述 DNS 查询服务器的基本流程是什么&#xff1f;DNS 劫持是什么&#xff1f;5、简述网关的…

Docker从认识到实践再到底层原理(九)|Docker Compose 容器编排

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…

Nacos与Eureka的区别

大家好我是苏麟今天说一说Nacos与Eureka的区别. Nacos Nacos的服务实例分为两种l类型&#xff1a; 临时实例&#xff1a;如果实例宕机超过一定时间&#xff0c;会从服务列表剔除&#xff0c;默认的类型。非临时实例&#xff1a;如果实例宕机&#xff0c;不会从服务列表剔除&…

十天学完基础数据结构-第四天(链表(Linked List))

链表的基本概念 链表是一种线性数据结构&#xff0c;与数组不同&#xff0c;链表的元素&#xff08;节点&#xff09;之间通过指针相互连接。链表有以下基本概念&#xff1a; 节点&#xff1a;链表中的每个数据项称为节点&#xff0c;每个节点包含数据和一个指向下一个节点的指…

2023年中国智能电视柜产量、需求量、市场规模及行业价格走势[图]

电视柜是随着电视机的发展和普及而演变出的家具种类&#xff0c;其主要作用是承载电视机&#xff0c;又称视听柜&#xff0c;随着生活水平的提高&#xff0c;与电视机相配套的电器设备也成为电视柜的收纳对象。 随着智能家具的发展&#xff0c;智能电视机柜的造型和风格都是有了…