目录
前言:
单值二叉树
问题描述
如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。
只有给定的树是单值二叉树时,才返回 true
;否则返回 false
。
解题思路
如果root为空,则返回true
判断root->left不为空并且左子树root->left->val的值不等于根节点root->val的值,返回false
判断root->right不为空并且右子树root->right->val的值不等于根节点root->val的值,返回false
最后返回遍历左右子树
代码
typedef struct TreeNode TreeNode;
bool isUnivalTree(struct TreeNode* root) {
if(root == NULL)
{
return true;
}
if(root->left && root->left->val != root->val)
{
return false;
}
if(root->right && root->right->val != root->val)
{
return false;
}
return isUnivalTree(root->left) && isUnivalTree(root->right);
}
相同的树
问题描述
给你两棵二叉树的根节点 p
和 q
,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
解题思路
判断根节点p,q同时是否为空,为空返回ture
判断根节点p,q一个为空一个不为空,返回false
判断根节点p,q都不为空值不相等,返回false
最后根节点p,q都不为空且相等则进入遍历,p,q左右并且,p->left和q->left、p->right和q->right比较。
代码
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
//p,q同时为空
if(p == NULL && q == NULL)
{
return true;
}
//p,q其中一个为空
if(p == NULL || q == NULL)
{
return false;
}
//p,q都不为空但值不相等
if(p->val != q->val)
{
return false;
}
return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}
对称二叉树
问题描述
给你一个二叉树的根节点 root
, 检查它是否轴对称。
解题思路
创建一个函数isSameTree函数
判断根节点p,q同时是否为空,为空返回ture
判断根节点p,q一个为空一个不为空,返回false
判断根节点p,q都不为空值不相等,返回false
根节点p,q都不为空且相等则进入遍历,p,q左右并且,p->left和q->right、p->right和q->left比较。
最后原函数返回isSameTree函数
代码
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
//p,q同时为空
if(p == NULL && q == NULL)
{
return true;
}
//p,q其中一个为空
if(p == NULL || q == NULL)
{
return false;
}
//p,q都不为空但值不相等
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);
}
另一棵树的子树
问题描述
给你两棵二叉树 root
和 subRoot
。检验 root
中是否包含和 subRoot
具有相同结构和节点值的子树。如果存在,返回 true
;否则,返回 false
。
二叉树 tree
的一棵子树包括 tree
的某个节点和这个节点的所有后代节点。tree
也可以看做它自身的一棵子树
解题思路
创建相同的树isSameTree函数
判断如果root为空,为空返回false
判断如果root=subRoot则进入isSameTree函数看以root为根节点的树是否与subRoot完全相同,相同返回true
最后递归root->left和subRoot或root->right和subRoot
代码
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
//p,q同时为空
if(p == NULL && q == NULL)
{
return true;
}
//p,q其中一个为空
if(p == NULL || q == NULL)
{
return false;
}
//p,q都不为空但值不相等
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);
}
前序遍历
问题描述
给你二叉树的根节点 root
,返回它节点值的 前序 遍历。
解题思路
创建一个二叉树结点个数的函数TreeSize
创建一个递归二叉树保存节点函数_preorderTraversal,传根节点root、存储数组int*arr、形参int*pi
如果根节点root为空,返回
arr数组里的形参(*pi)++保存节点root的值
遍历左右节点
*returnSize储存结点函数TreeSize
创建int*returnArr储存动态申请空间arr大小
创建函数i
调用递归二叉树保存节点函数_preorderTraversal传root、returnArr、i
最后返回returnArr
代码
typedef struct TreeNode TreeNode;
int TreeSize(TreeNode* root)
{
if(root == NULL)
{
return 0;
}
return 1+TreeSize(root->left)+TreeSize(root->right);
}
void _preorderTraversal(TreeNode*root,int*arr,int*pi)
{
if(root == NULL)
{
return ;
}
arr[(*pi)++]=root->val;
_preorderTraversal(root->left,arr,pi);
_preorderTraversal(root->right,arr,pi);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
//第一步:先求出二叉树节点个数
*returnSize=TreeSize(root);
//第二部:动态申请内容--arr数组
int*returnArr=(int*)malloc(sizeof(int)*(*returnSize));
int i =0;
_preorderTraversal(root,returnArr,&i);
return returnArr;
}
中序遍历
问题描述
给定一个二叉树的根节点 root
,返回它的中序遍历。
解题思路
创建一个二叉树结点个数的函数TreeSize
创建一个递归二叉树保存节点函数_inorderTraversal,传根节点root、存储数组int*arr、形参int*pi
如果根节点root为空,返回
遍历左节点
arr数组里的形参(*pi)++保存节点root的值
遍历右节点
*returnSize储存结点函数TreeSize
创建int*returnArr储存动态申请空间arr大小
创建函数i
调用递归二叉树保存节点函数_inorderTraversal传root、returnArr、i
最后返回returnArr
代码
typedef struct TreeNode TreeNode;
int TreeSize(TreeNode* root)
{
if(root == NULL)
{
return 0;
}
return 1+TreeSize(root->left)+TreeSize(root->right);
}
void _inorderTraversal(TreeNode*root,int*arr,int*pi)
{
if(root == NULL)
{
return ;
}
_inorderTraversal(root->left,arr,pi);
arr[(*pi)++]=root->val;
_inorderTraversal(root->right,arr,pi);
}
int* inorderTraversal(struct TreeNode* root, int* returnSize) {
//第一步:先求出二叉树节点个数
*returnSize=TreeSize(root);
//第二部:动态申请内容--arr数组
int*returnArr=(int*)malloc(sizeof(int)*(*returnSize));
int i =0;
_inorderTraversal(root,returnArr,&i);
return returnArr;
}
后序遍历
问题描述
给你一棵二叉树的根节点 root
,返回其节点值的 后序遍历 。
解题思路
创建一个二叉树结点个数的函数TreeSize
创建一个递归二叉树保存节点函数_postorderTraversal,传根节点root、存储数组int*arr、形参int*pi
如果根节点root为空,返回
遍历左右节点
arr数组里的形参(*pi)++保存节点root的值
*returnSize储存结点函数TreeSize
创建int*returnArr储存动态申请空间arr大小
创建函数i
调用递归二叉树保存节点函数_postorderTraversal传root、returnArr、i
最后返回returnArr
代码
typedef struct TreeNode TreeNode;
int TreeSize(TreeNode* root)
{
if(root == NULL)
{
return 0;
}
return 1+TreeSize(root->left)+TreeSize(root->right);
}
void _postorderTraversal(TreeNode*root,int*arr,int*pi)
{
if(root == NULL)
{
return ;
}
_postorderTraversal(root->left,arr,pi);
_postorderTraversal(root->right,arr,pi);
arr[(*pi)++]=root->val;
}
int* postorderTraversal(struct TreeNode* root, int* returnSize) {
//第一步:先求出二叉树节点个数
*returnSize=TreeSize(root);
//第二部:动态申请内容--arr数组
int*returnArr=(int*)malloc(sizeof(int)*(*returnSize));
int i =0;
_postorderTraversal(root,returnArr,&i);
return returnArr;
}
⼆叉树的构建及遍历
问题描述
编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。
输入描述:
输入包括1行字符串,长度不超过100。
输出描述:
可能有多组测试数据,对于每组数据, 输出将输入字符串建立二叉树后中序遍历的序列,每个字符后面都有一个空格。 每个输出结果占一行。
解题思路
代码
#include <stdio.h>
#include <stdlib.h>
/*
读取用户输入,保存在数组中,这个字符串的内容刚好是二叉树的前序遍历
我们根据这个前序遍历的结果来创建二叉树
再对二叉树进行中序遍历,输出中序遍历的结果
*/
/*
abc##de#g##f###
对于这个字符串,c是b的左子树,b是a的左子树
*/
/*
若遍历中没有给出NULL节点的情况,是不能根据某一个遍历来创建二叉树的
*/
typedef struct BinaryTreeNode//定义二叉树节点结构类型
{
char data;
struct BinaryTreeNode*left;
struct BinaryTreeNode*right;
}BTNode;
BTNode*buyNode(char x)//创建节点
{
BTNode*newnode=(BTNode*)malloc(sizeof(BTNode));
newnode->data=x;
newnode->left=newnode->right=NULL;
return newnode;
}
BTNode*createTree(char*arr,int*pi)//创建二叉树,返回根节点,第一个参数是字符串,第二个参数是下标
{
if(arr[*pi]=='#')
{
(*pi)++;//不要忘了往后面接着走
return NULL;
}
BTNode*root=buyNode(arr[(*pi)++]);//将数组中的数据存储在二叉树中,将数组中的数据传到二叉树节点内
root->left=createTree(arr,pi); //然后进行二叉树左节点的创建
root->right=createTree(arr,pi); //二叉树右节点的创建
return root;//返回根节点
}
void InOeder(BTNode*root)
{
if(root==NULL)
{
return;
}
InOeder(root->left);//递归左子树
printf("%c ",root->data);//打印根节点
InOeder(root->right);//递归右子树
}
int main()
{
//读取用户输入的字符串保存在字符数组中
char arr[100];
scanf("%s",arr);
//根据字符串(前序遍历)创建二叉树
int i=0;
BTNode*root=createTree(arr,&i);
//这里的root是创建的二叉树的根节点
//输出二叉树的中序遍历
InOeder(root);
return 0;
}