【数据结构与算法】二叉树基础OJ -- 上 (巩固提高)-2

简介: 【数据结构与算法】二叉树基础OJ -- 上 (巩固提高)-2

【数据结构与算法】二叉树基础OJ -- 上 (巩固提高)-1https://developer.aliyun.com/article/1456936


leetcode 144.二叉树的前序遍历(需要数组存储)

题目来源:144. 二叉树的前序遍历 - 力扣(LeetCode)


题目描述:

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。


示例:

00b88033e4cf4189968fd85fb64733f5.png



解题思路:

       首先用TreeSize函数算出二叉树的节点数量,具体实现看这篇文章:http://t.csdnimg.cn/DvuEU


      接着用*returnsize这个值接收,为什么要解引用?因为传过来的是size的地址-->&size


图解在这:实现其main函数:


5995163aafb0413a8798d24bc75e54ed.png


        接着malloc一块空间,定义指针int*a指向,定义变量i,接着传入preorder函数,进行前序遍历,之后返回a的地址。


代码实现:


int TreeSize(struct TreeNode* root)
{
    return root == NULL ? 0:TreeSize(root->left) + TreeSize(root->right)+1; 
}
void preorder(struct TreeNode*root,int*a,int*i)
{
    if(root==NULL)
    {
        return ;
    }
    a[(*i)++]=root->val;
    preorder(root->left,a,i);
    preorder(root->right,a,i);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize)
{
    *returnSize = TreeSize(root);
    int* a= malloc(*returnSize*sizeof(struct TreeNode));
    int i=0;
    preorder(root,a,&i);
    return a;
}


执行:


1e24514f092146918d124bac2b6e0cf0.png

关于此题有两个疑问:


       1.用局部变量,下面的这个代码可以吗?


int TreeSize(struct TreeNode* root)
{
    return root == NULL ? 0:TreeSize(root->left) + TreeSize(root->right)+1; 
}
void _preorder(struct TreeNode* root, int* a,int i)
{
  if (root == NULL)
  return;
  //用指针的方式是为了不在不同栈帧内创建i
  a[i++] = root->val;
  _preorder(root->left, a,i);
  _preorder(root->right, a,i);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize)
{
  *returnSize = TreeSize(root);
  int* a = (int*)malloc(*returnSize * sizeof(int));
  int i = 0;
  _preorder(root,a,i);
  return a;
}


结果是不行,为什么?用局部变量就不行吗?



971bbad259c64b32b4e78531bbc1401d.png

以下是我的理解:


f76322b6a3304d18b82ff36d5db4b603.png


2.全局变量可以吗?


       可以,但是先列举问题:

0652babe9be940a2bfb6a59809f29767.png


解析:        


虽然全局变量 i 在定义时已经被初始化为 0,但是全局变量的赋值操作只会在程序启动时执行一次。每次调用 _preorder 函数时,由于没有显式地给 i 赋新的值,i 的值会保持上一次调用结束时的值。这样会导致多次调用 _preorder 函数时,节点值被存储在错误的位置,结果可能不符合预期。
        因此,在函数内部显式地给 i 赋值为 0,可以确保每次调用 _preorder 函数时都从数组 a 的开头位置开始存储节点的值,避免出现错误的索引位置。

leetcode 572.另一棵树的子树

题目来源:572. 另一棵树的子树 - 力扣(LeetCode)


题目描述:

     

给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。
        二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

示例:


00b32b1a58bc4d1da7b99d396d6789ab.png


解题思路:

首先,判断 root 是否为 NULL,如果是,则不存在子树,返回 false。
接着,调用 isSameTree 函数,判断 root 和 subRoot 是否相同,如果是,则 subRoot 是 root 的子树,返回 true。
如果以上条件都不满足,递归调用 isSubtree 函数,分别判断 subRoot 是否是 root 的左子树的子树,或者是 root 的右子树的子树。只要有一边存在子树,就返回 true。
如果都不满足,则 subRoot 不是 root 的子树,返回 false。

图解:


8b3eb6012a31426b98d64e4d8c64406c.png


代码实现:


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


代码执行:


  06631a9045094dc5b2156088b7bda6a7.png    

相关文章
|
7天前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
10天前
|
存储 缓存 算法
如何提高二叉树遍历算法的效率?
选择合适的遍历算法,如按层次遍历树时使用广度优先搜索(BFS),中序遍历二叉搜索树以获得有序序列。优化数据结构,如使用线索二叉树减少空指针判断,自定义节点类增加辅助信息。利用递归与非递归的特点,避免栈溢出问题。多线程并行遍历提高速度,注意线程安全。缓存中间结果,避免重复计算。预先计算并存储信息,提高遍历效率。综合运用这些方法,提高二叉树遍历算法的效率。
29 5
|
14天前
|
C语言
【数据结构】二叉树(c语言)(附源码)
本文介绍了如何使用链式结构实现二叉树的基本功能,包括前序、中序、后序和层序遍历,统计节点个数和树的高度,查找节点,判断是否为完全二叉树,以及销毁二叉树。通过手动创建一棵二叉树,详细讲解了每个功能的实现方法和代码示例,帮助读者深入理解递归和数据结构的应用。
63 8
|
13天前
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
23 0
|
1月前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
19 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
1月前
|
存储 算法 搜索推荐
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
这篇文章主要介绍了顺序存储二叉树和线索化二叉树的概念、特点、实现方式以及应用场景。
20 0
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
|
1月前
|
存储 算法
探索数据结构:分支的世界之二叉树与堆
探索数据结构:分支的世界之二叉树与堆
|
15天前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
90 9
|
6天前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
15 1
|
9天前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。