作者:[南航科院小张
南航科院小张的博客
学习知识不只是要懂,还要会用;想要找到好的工作,这里给大家介绍一件可以斩获诸多大厂offer的利器–牛客网
点击免费注册和我一起开始刷题之路吧!!!
一、二叉树的前序遍历
它要求不是我们直接遍历打印出来,而是malloc一块空间存放节点数据然后返回空间;这个时候先遍历一遍求出二叉树的节点个数,然后malloc相应的空间大小,然后根据前序遍历把节点数据放到数组中,但是如果用下标来放数据的话,传地址来做下标开最简便,要是传值的话会发生错误;最后返回数组;
int BinaryTreeSize(struct TreeNode* root){
if(root==NULL)
return 0;
return BinaryTreeSize(root->left)+BinaryTreeSize(root->right)+1;
}
void BTPrevOrder(struct TreeNode* root,int* a,int* sz){
if(root==NULL)
return;
a[*sz]=root->val;
(*sz)++;
BTPrevOrder(root->left,a,sz);
BTPrevOrder(root->right,a,sz);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize){
int n=0;
n=BinaryTreeSize(root);
*returnSize=n;
int* a=(int*)malloc(sizeof(int)*n);
int sz=0;
BTPrevOrder(root,a,&sz);
return a;
}
二. 单值二叉树
利用递归思想,分治,分而治之;比较根和左右子树的值,有不相同的就返回false,都相同就继续,让左右子树分别变成根,跟自己的子树比,一直递归下去;
bool isUnivalTree(struct TreeNode* root){
if(root==NULL)
return true;
if(root->left&&root->val!=root->left->val)
return false;
if(root->right&&root->val!=root->right->val)
return false;
return isUnivalTree(root->left)&&isUnivalTree(root->right);
}
三. 二叉树的最大深度
这题还是递归,树的高度是自己的高度(1)+左右子树高的子树的高度;
就是看子树那个更高,自己的高度1加上高的子树的高度就是树的高度;
然后子树的高度又分成自己的高度1加上子树的子树那个高的高度,一直分治下去;
int maxDepth(struct TreeNode* root){
if(root==NULL)
return 0;
int lh=maxDepth(root->left);
int rh=maxDepth(root->right);
return lh>rh?lh+1:rh+1;
}
四. 翻转二叉树
仔细看一下题目,要是把每个节点的左右子树都交换过来,不就得到答案了吗?又是递归分治问题;
struct TreeNode* invertTree(struct TreeNode* root){
if(root==NULL)
return NULL;
invertTree(root->left);
invertTree(root->right);
struct TreeNode* temp=root->left;
root->left=root->right;
root->right=temp;
return root;
}
五. 相同的树
一个一个节点遍历对比嘛,但是要记得特殊情况,比如一个节点是空,或者两个节点都是空的情况;
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
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 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);
}
七. 另一颗树的子树
把Root树的每一个节点当成一棵二叉树最大的根,一个一个和Subroot比较,判断是否相同,还得用上上题的判断树相等的代码;
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
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);
}
八. 平衡二叉树
把每个左右子树当成根节点,然后子树的左右子树的高度是否符合,一一判断嘛,还是用递归;
int maxDepth(struct TreeNode* root){
if(root==NULL)
return 0;
int lh=maxDepth(root->left);
int rh=maxDepth(root->right);
return lh>rh?lh+1:rh+1;
}
bool isBalanced(struct TreeNode* root){
if(root==NULL)
return true;
int lh=maxDepth(root->left);
int rh=maxDepth(root->right);
if(abs(lh-rh)>1)
return false;
return isBalanced(root->left)&&isBalanced(root->right);
}
九. 二叉树遍历
先搞一个数组放前序遍历的数据,然后再搞一个创建二叉树的函数,记得传下标要地址哦,创建二叉树的时候要搞前序的递归一个一个链接节点;然后树搞好以后就直接简单的中序遍历了;代码实现可能有点点挑战,但是实际上不太难的哈;
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef char BTDataType;
typedef struct BinaryTreeNode{
BTDataType data;
struct BinaryTreeNode* left;struct BinaryTreeNode* right;
}BTNode;
BTNode* BinaryTreeCreate(char* a,int* n){
if(a[*n]=='#'){
(*n)++;
return NULL;
}
BTNode* root=(BTNode*)malloc(sizeof(BTNode));
if(root==NULL){
perror("malloc fail");
exit(-1);
}
root->data=a[*n];
(*n)++;
root->left=BinaryTreeCreate(a, n);
root->right=BinaryTreeCreate(a,n);
return root;
}
void InOrder(BTNode* root){
if(root==NULL)
return;
InOrder(root->left);
printf("%c ",root->data);
InOrder(root->right);
}
int main(){
char arr[100]={0};
scanf("%s",arr);
int n=0;
BTNode* root=BinaryTreeCreate(arr,&n);
InOrder(root);
return 0;
}
总结
刷题对我们的知识点的掌握和思维的锻炼是有较大的帮助的,多刷题对我们有很多好处的哦