二叉树(中)+Leetcode每日一题——“数据结构与算法”“剑指Offer55-I. 二叉树的深度”“100.相同的树”“965.单值二叉树”

简介: 二叉树(中)+Leetcode每日一题——“数据结构与算法”“剑指Offer55-I. 二叉树的深度”“100.相同的树”“965.单值二叉树”

二叉树链式结构的实现

求二叉树的高度

//求二叉树的高度
int BTreeHeight(BTNode* root)
{
  if (root == NULL)
  {
    return 0;
  }
  else
  {
    return BTreeHeight(root->left) > BTreeHeight(root->right)
      ? BTreeHeight(root->left) + 1 : BTreeHeight(root->right) + 1;
  }
}

但是这种写法有很大的问题!!!

下面,我们来看leetcode上面有一个类似的题目。

会发现:这种写法是过不了的!!!

当这棵树特别大的时候,leetcode会提示超出时间限制!!!

下面,我来举一个生动形象的例子

在这张图上,所有的领导都不记事。校长找院长1,院长1找辅导员1,辅导员1找班长1,班长1返回了一个结果给辅导员1,辅导员1又找班长2,班长2也返回了一个结果给辅导员1,但是这个辅导员1只比较了班长1和班长2所返回的结果谁大谁小,并没有把数据记录下来。等到班长2返回完结果之后,辅导员1又再一次找班长1要数据(班长1的数据比较好),班长1又要再一次返回数据结果。现在,辅导员1终于可以把结果返回给院长1了, 然后,院长1开始找辅导员2,辅导员2找班长3,班长3返回结果给辅导员2,辅导员2找班长4,班长4也返回结果给辅导员2,但是辅导员2仍然只是比较了班长3和班长4所返回的数据结果的大小,并没有把数据记录下来,假设班长4的数据比较好,也就是:班长4刚刚把数据报给辅导员2,回到宿舍,辅导员紧接着打了个电话给班长4,要他来汇报数据。现在辅导员2终于把数据汇报给院长1了,但是,这个院长1只比较了辅导员1和辅导员2所返回的数据结果的大小,还是没有记录数据。假设辅导员1的数据比较好,辅导员1又得找两个班长重复上面的过程(关键是辅导员1不记事,再一次比较了班长1和班长2的数据后,又得把班长1叫过去汇报数据)(班长1:我真是栓Q,没完没了了是吧)

这样是非常恐怖的!!!

调用的次数成等比数列(成倍地增加,每一层都是一个叠加的double)

所以,这个题目的最优解是:

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

所以求二叉树的高度的源代码:

//求二叉树的高度
int BTreeHeight(BTNode* root)
{
  if (root == NULL)
  {
    return 0;
  }
  else
  {
    int leftHeight = BTreeHeight(root->left);
    int rightHeight = BTreeHeight(root->right);
    return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
  }
}

二叉树第k层结点个数

子问题:转换成左子树的第k-1层和右子树的第k-1层

结束条件:k==1且结点不为空

// 二叉树第k层节点个数
int BTreeLevelKSize(BTNode* root, int k)
{
  assert(k > 0);
  if (root == NULL)//无论k是多少
  {
    return 0;
  }
  //root一定不为空
  if (k == 1)
  {
    return 1;
  }
  //root不为空并且k不为1
  return BTreeLevelKSize(root->left, k - 1) + BTreeLevelKSize(root->right, k - 1);
}

使用前序比较!!!

二叉树里面不敢轻易使用断言(因为二叉树里面有NULL)

bool isSameTree(struct TreeNode* p, struct TreeNode* q){
    //两个都为空
    if(p==NULL&&q==NULL)
    {
        return true;
    }
    //一个为空,另一个不为空
    if((p==NULL&&q!=NULL)||(p!=NULL&&q==NULL))
    {
        return false;
    }
    //根不相等
    if(p->val!=q->val)
    {
        return false;
    }
    return isSameTree(p->left,q->left)
    &&isSameTree(p->right,q->right);
}

二叉树查找值为x的结点

使用前序查找!!!        根         左子树        右子树

// 二叉树查找值为x的节点
BTNode* BTreeFind(BTNode* root, BTDataType x)
{
  if (root == NULL)
  {
    return NULL;
  }
  if (root->data == x)
  {
    return root;
  }
  BTNode* ret1 = BTreeFind(root->left, x);
  if (ret1)
  {
    return ret1;
  }
  BTNode* ret2 = BTreeFind(root->right, x);
  if (ret2)
  {
    return ret2;
  }
  return NULL;
}

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


二叉树的源代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef int BTDataType;
typedef struct BinaryTreeNode
{
   BTDataType data;
   struct BinaryTreeNode* left;
   struct BinaryTreeNode* right;
}BTNode;

BTNode* BuyNode(BTDataType x)
{
   BTNode* node = (BTNode*)malloc(sizeof(BTNode));
   if (node == NULL)
   {
       perror("malloc fail");
       return NULL;
   }
   node->data = x;
   node->left = NULL;
   node->right = NULL;
   return node;
}

BTNode* CreatBinaryTree()
{
   BTNode* node1 = BuyNode(1);
   BTNode* node2 = BuyNode(2);
   BTNode* node3 = BuyNode(3);
   BTNode* node4 = BuyNode(4);
   BTNode* node5 = BuyNode(5);
   BTNode* node6 = BuyNode(6);

   node1->left = node2;
   node1->right = node4;
   node2->left = node3;
   node4->left = node5;
   node4->right = node6;
   return node1;
}

//求二叉树的高度
int BTreeHeight(BTNode* root)
{
   if (root == NULL)
   {
       return 0;
   }
   else
   {
       int leftHeight = BTreeHeight(root->left);
       int rightHeight = BTreeHeight(root->right);
       return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
   }
}

// 二叉树第k层节点个数
int BTreeLevelKSize(BTNode* root, int k)
{
   assert(k > 0);
   if (root == NULL)//无论k是多少
   {
       return 0;
   }
   //root一定不为空
   if (k == 1)
   {
       return 1;
   }
   //root不为空并且k不为1
   return BTreeLevelKSize(root->left, k - 1) + BTreeLevelKSize(root->right, k - 1);
}

// 二叉树查找值为x的节点
BTNode* BTreeFind(BTNode* root, BTDataType x)
{
   if (root == NULL)
   {
       return NULL;
   }
   if (root->data == x)
   {
       return root;
   }
   BTNode* ret1 = BTreeFind(root->left, x);
   if (ret1)
   {
       return ret1;
   }
   BTNode* ret2 = BTreeFind(root->right, x);
   if (ret2)
   {
       return ret2;
   }
   return NULL;
}

int main()
{

   printf("BTreeHeight:%d\n", BTreeHeight(root));

   printf("BTreeLevelKSize:%d\n", BTreeLevelKSize(root, 3));

   printf("BTreeFind:%p\n", BTreeFind(root, 3));

   return 0;
}


好啦,小雅兰今天的内容就到这里啦,还要继续加油呀!!!


相关文章
|
1月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
38 0
|
9天前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
12天前
|
存储 缓存 算法
如何提高二叉树遍历算法的效率?
选择合适的遍历算法,如按层次遍历树时使用广度优先搜索(BFS),中序遍历二叉搜索树以获得有序序列。优化数据结构,如使用线索二叉树减少空指针判断,自定义节点类增加辅助信息。利用递归与非递归的特点,避免栈溢出问题。多线程并行遍历提高速度,注意线程安全。缓存中间结果,避免重复计算。预先计算并存储信息,提高遍历效率。综合运用这些方法,提高二叉树遍历算法的效率。
34 5
|
12天前
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
|
15天前
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
24 0
|
1月前
|
算法
每日一道算法题(Leetcode 20)
每日一道算法题(Leetcode 20)
24 2
|
1月前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
20 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
1月前
|
存储 算法 搜索推荐
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
这篇文章主要介绍了顺序存储二叉树和线索化二叉树的概念、特点、实现方式以及应用场景。
23 0
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
|
1月前
|
存储 算法
【二叉树】—— 算法题
【二叉树】—— 算法题
【二叉树】—— 算法题
|
1月前
|
存储 算法
数据结构与算法学习十六:树的知识、二叉树、二叉树的遍历(前序、中序、后序、层次)、二叉树的查找(前序、中序、后序、层次)、二叉树的删除
这篇文章主要介绍了树和二叉树的基础知识,包括树的存储方式、二叉树的定义、遍历方法(前序、中序、后序、层次遍历),以及二叉树的查找和删除操作。
25 0