> 文章列表 > 【数据结构】二叉树OJ题

【数据结构】二叉树OJ题

【数据结构】二叉树OJ题

 😽PREFACE
🎁欢迎各位→点赞👍 + 收藏⭐ + 评论📝
📢系列专栏:数据结构
🔊本专栏主要更新的是数据结构部分知识点
💪种一棵树最好是十年前其次是现在

目录

1.单值二叉树 

2.相同的树

3.前序遍历

4.另一棵树的子树

5.二叉树遍历


1.单值二叉树 

题目链接:力扣

 代码演示:

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

2.相同的树

题目链接:力扣

  • 思路:首先如果p,q都是空,那么满足条件,直接返回true。如果其中一个为空,则返回false;如果两个都不为空,这个时候还应该分两种情况,如果对应的值不等,那么返回false,如果相等则继续递归比较它们的左右子树。
  • 代码实现:
    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);
    }

3.前序遍历

题目链接:力扣

  • 思路:在上篇文章我们已经实现了前序遍历,而此题明显就是让我们去模拟实现,题中条件明确指出要动态开辟一块数组来存放数据,关键是开辟多大空间呢?所以这里用到第一个辅助函数——求节点个数函数(TreeSize)。接下来就是依次递归分治思想,但是我们发现了一个致命的缺陷,就是每次递归到主函数时都要malloc,这样是十分消耗栈帧的,因此还需要构造第二个辅助函数专门用于递归。
  • 注意点:传节点个数时,一定要传地址。因为每次递归都会建立栈帧,递归完就会销毁,无法保存。此外,*returnSize是要返回数组元素的,返回给调用者。
  • 代码演示:
    //写一个函数用于求出二叉树节点的个数,方便后面malloc
    int TreeSize(struct TreeNode* root)
    {return root==NULL?0:TreeSize(root->left)+TreeSize(root->right)+1;
    }//写一个专门用于递归的函数,防止用主函数递归时每次都要malloc
    void preorder(struct TreeNode* root,int* a,int* pi)
    {if(root==NULL){return;}a[(*pi)++]=root->val;preorder(root->left,a,pi);preorder(root->right,a,pi);
    }int* preorderTraversal(struct TreeNode* root, int* returnSize){//接受节点个数*returnSize=TreeSize(root);//动态开辟数组int* a=(int*)malloc(*returnSize*sizeof(int));int i=0;//i一定要传地址,因为每次递归都会建立栈帧,递归完之后就会销毁preorder(root,a,&i);return a;
    }

4.另一棵树的子树

题目链接:力扣

  • 思路:遍历左边树的每一个节点使其作为子树的根,跟右树的子树都比较一下,此时就可以cv之前写过的函数(isSameTree) ,用来比较两棵树是否相同,依次比较,如果是子树,则返回true
  • 代码演示:
    //判断两棵树是否相同
    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;//是子树就返回true}return isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);
    }

     

5.二叉树遍历

题目链接:二叉树遍历_牛客题霸_牛客网

  •  思路:首先本题要求根据我们输入的字符串将其构建成树,再按照中序的遍历方式输出。例如:
  •  构造时要按照先序遍历,递归过程如下:首先遇到a,不是‘#’,接着向下构造左子树b,同理再向下构造左子树c,这个时候遇到了‘#’。则回溯到c,再来构造c的右子树,结果又遇到‘#’,因此再向上回溯到b,此时再构造b的右子树,接着同理……
  • 如果已经创建好二叉树的结构了,下面只需要按照中序遍历打印出来即可。
  • 代码演示:
    //创建二叉树结构
    struct TreeNode
    {struct TreeNode* left;struct TreeNode* right;char val;
    };//创建节点,先序结构创建
    struct TreeNode* CreatTree(char* a,int* pi)
    {if(a[*pi]=='#'){(*pi)++;return NULL;}struct TreeNode* root=(struct TreeNode*)malloc(sizeof(struct TreeNode));root->val=a[(*pi)++];root->left=CreatTree(a,pi);root->right=CreatTree(a,pi);return root;
    }//中序输出
    void InOrder(struct TreeNode* root)
    {if(root==NULL){return ;}InOrder(root->left);printf("%c ",root->val);InOrder(root->right);
    }int main() {char a[100];scanf("%s",a);int i=0;struct TreeNode* root=CreatTree(a,&i);InOrder(root);return 0;
    }