二叉树相关OJ题

简介: 二叉树相关OJ题

                                                     创作不易,感谢三连!!

一、选择题

1、某二叉树共有 399 个结点,其中有 199 个度为 2 的结点,则该二叉树中的叶子结点数为( )

A.不存在这样的二叉树

B.200

C.198

D.199

解析:选B,根据n0=n2+1的结论(这个结论不清楚的看博主的关于二叉树概念的文章有证明),就是度为0的节点始终比度为2的节点多一个,所以这题就很显然选B了!!

2、在具有 2n 个结点的完全二叉树中,叶子结点个数为( )

A n

B n+1

C n-1

D n/2

解析:选A ,原因如下

3、一棵完全二叉树的节点数位为531个,那么这棵树的高度为( )

A 11

B 10

C 8

D 12

解析:选B,根据结论——满二叉树的节点N数量=2^h-1,如果高度为8,那么节点最多有255个,当高度为10时,节点最多有1023个,所以高度只能是10

4、一个具有767个节点的完全二叉树,其叶子节点个数为()

A 383

B 384

C 385

D 386

解析:选B,因为度为2的节点数肯定并度为0的节点数少1个,所以n0和n2一个是奇数一个是偶数,所以n1只能是偶数,又因为完全二叉树n1只有可能是0或者1,所以n1只能取0,所以n0=384,n2=383

5、一组记录排序码为(5 11 7 2 3 17),则利用堆排序方法建立的初始堆为()。
A(11 5 7 2 3 17)
B(11 5 7 2 17 3)
C(17 11 7 2 3 5)
D(17 11 7 5 3 2)
E(17 7 11 3 5 2)
F(17 7 11 3 2 5)

解析:选C 先画出来,再不断向下调整

6、最小堆[0,3,2,5,7,4,6,8],在删除堆顶元素0之后,其结果是()

A[3,2,5,7,4,6,8]

B[2,3,5,7,4,6,8]

C[2,3,4,5,7,8,6]

D[2,3,4,5,6,7,8]

解析:选C,还是画出来再调整

二、单值二叉树

OJ:单值二叉树

bool isUnivalTree(struct TreeNode* root)
{
   if(root==NULL)//a==b,a==c,->b==c
   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);
}

三、检查两棵树是否相同

OJ:判断两棵树是否相同

这个在博主讲解二叉树链式存储中有仔细分析过了!!

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

四、对称二叉树

OJ:对称二叉树

bool _isSymmetric(struct TreeNode* leftroot,struct TreeNode* rightroot)
{
    //都为空,对称
    if(leftroot==NULL&&rightroot==NULL)
    return true;
    //一个为空一个不为空,不对称
    if(leftroot==NULL||rightroot==NULL)
    return false;
    //都不为空,就可以看值了,如果值不相等,不对称
    if(leftroot->val!=rightroot->val)
    return false;
    //此时都不为空,且值相等,就走递归找下一个
    //左树的左子树要跟右树的右子树相比
    //左树的右子树要跟右树的左子树相比
    return _isSymmetric(leftroot->left,rightroot->right)&&
           _isSymmetric(leftroot->right,rightroot->left);
}
bool isSymmetric(struct TreeNode* root) 
{
  if(root==NULL)
  return true;
  //根不对称,就去找左右子树比 相当于是拆成两棵树的了
  return _isSymmetric(root->left,root->right);
}

五、二叉树的前序遍历

OJ:二叉树的前序遍历

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是结点数
    *returnSize=TreeSize(root);
     int *a=(int *)malloc(*returnSize*sizeof(int));
     int i=0;
     _preorder(root,a,&i);
     return a;
}

六、二叉树的中序遍历

OJ:二叉树的中序遍历

int i=0;
 int TreeSize(struct TreeNode* root)
{
    return root==NULL?0:TreeSize(root->left)+TreeSize(root->right)+1;
}
void _inorderTraversal(struct TreeNode* root,int *a)
{
          if(root==NULL)
          return ;
          _inorderTraversal(root->left,a);
          a[i++]=root->val;
          _inorderTraversal(root->right,a);
}
int* inorderTraversal(struct TreeNode* root, int* returnSize) 
{
     //returnsize是结点数
    *returnSize=TreeSize(root);
     int *a=(int *)malloc(*returnSize*sizeof(int));
     i=0;//全局变量一定要记得赋0
     _inorderTraversal(root,a);//必须构造新函数去递归,因为在原函数递归会不断创建新的数组
     return a;
}

注:这题跟上题是差不多的,我稍微改了一下,这里数组的下标我不用指针去接受参数了,而是直接设置一个全局变量i!!要注意的是,因为力扣的测试可能会多次调用这个函数,所以我们一定要在递归函数运行前让i=0!!否则就会i就会一直叠加下去导致越界!! (还有一个注意事项就是,这里千万不要使用静态的局部变量,虽然他也同样可以在函数栈帧销毁时不被释放,但是他的作用域很小,不能让我们在主函数中让i=0)

但是尽量少使用全局变量!!

七、二叉树的后序遍历

OJ:二叉树的后序遍历

void _postorder(struct TreeNode* root,int *arr,int *arrsize)
{
    if(root==NULL)
    return;
    _postorder(root->left,arr,arrsize);
    _postorder(root->right,arr,arrsize);
    arr[(*arrsize)++]=root->val;
}
int* postorderTraversal(struct TreeNode* root, int* returnSize) 
{
    int *arr=(int*)malloc(100*sizeof(int));
    *returnSize=0;
     _postorder(root,arr,returnSize);
    return arr;
}

注:这题和前两题差不多,但是又进行了改进,我们发现了题目的一个条件

     也就是说我们动态开辟100个空间的话是绝对不会越界的,所以就不需要通过自己封装一个treesize函数来计算节点个数数量了!! 那我们要怎么去让returnsize返回节点个数的值的??方法就是把*returnsize初始化为0作为下标,每次放进一个值的时候*returnsize就会++一次,当后序遍历结束的时候,returnsize恰好又多+了一次,正好表示节点个数的数量!!

八、另一颗树的子树

OJ:另一颗树的子树

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;//为空就不比较的,因为subRoot是至少有一个节点的。
     if(isSametree(root,subRoot))
     return true;
     return isSubtree(root->left, subRoot)||isSubtree(root->right, subRoot);
     //左子树和右子树只要有一个找到了,就返回true
}

      关键就是我们每遍历到一个节点,都要尝试把他往下遍历去和另外一个子树进行比较!!所以单独封装了一个比较两个树是否相同的函数,该树每遍历一次节点就去调用一次,最后在用||操作符,因为左子树和右子树只要有一个找到就可以了!!

九、二叉树的构建及遍历

OJ:二叉树的构建及遍历

typedef char BTDataType;
typedef struct BTtreeNode
{
    BTDataType val;
    struct BTtreeNode*left;
    struct BTtreeNode*right;
}BTtreeNode;
BTtreeNode* BuyNode(BTDataType x)
{
    BTtreeNode*newnode=(BTDataType*)malloc(sizeof(BTDataType));
      newnode->left=newnode->right=NULL;
      newnode->val=x;
      if(newnode==NULL)
      {
        perror("malloc fail");
        exit(1);
      }
      return newnode;
}
BTtreeNode* CreateTree(BTDataType*a,int *pi)
{
    if(a[*pi]=='#')
    {
    (*pi)++;
    return NULL;
    }
    BTtreeNode*root=BuyNode(a[(*pi)++]);
    root->left=CreateTree(a,pi);
    root->right=CreateTree(a,pi);
    return root;
}
void InOrder(BTtreeNode*root)
{
    if(root==NULL)
    return;
    InOrder(root->left);
    printf("%c ",root->val);
    InOrder(root->right);
}
int main()
{
    char arr[100];
    scanf("%s",arr);
    int i=0;
    BTtreeNode*root=CreateTree(arr,&i);
    InOrder(root);
    printf("\n");
    return 0;
}

这题就是将二叉树的构建和链式结构的中序遍历结合起来了!!

相关文章
|
机器学习/深度学习 并行计算 API
【GPU】CUDA是什么?以及学习路线图!
【GPU】CUDA是什么?以及学习路线图!
7918 0
|
8月前
|
安全 机器人 定位技术
2026年支持二次开发的轮式机器人技术深度解析与主流产品推荐
2025年轮式机器人迈向“认知智能+定制开发”新阶段。凭借高稳定性与长续航,广泛应用于教育、医疗与商业服务。“标准化底盘+定制化开发”成主流,融合大语言模型、SLAM与虚拟化技术,实现感知、决策与安全控制。本文解析认知架构、实时混核系统与数字孪生等核心技术,并推荐猎户星空、云迹、优必选、擎朗等主流开放平台,助力开发者高效落地场景应用。(238字)
|
4月前
|
存储 运维 监控
智算中心建设项目一般过程解析
智算中心是支撑AI、大数据发展的新型算力基础设施。九章云极主导建设运营,覆盖立项、设计、部署等六阶段全流程,3年内目标纳管10万P算力。(239字)
|
4月前
|
存储 弹性计算 人工智能
2026年最新阿里云服务器租用费用:轻量、ECS及GPU云服务器活动价格表
2026年阿里云提供丰富且具竞争力的云服务器产品线,涵盖轻量应用服务器、ECS及GPU云服务器,满足不同用户需求。轻量应用服务器适合个人开发者等,有38元/年等限时抢购和日常优惠套餐。ECS云服务器有低价长效特惠,如经济型e实例99元/年,u1实例199元/年,还有经济型e实例、通用算力型u2i实例及第九代企业级实例的深度折扣活动。GPU云服务器适合AI和计算密集型任务,有多种规格和价格。用户可通过精准匹配需求、善用优惠券、选择合适购买周期降低成本上云。
|
6月前
|
人工智能 运维 机器人
过完年AI世界全变了!老金帮你5分钟看完春节13个重磅发布
春节20天,国产AI密集发布13款重磅产品:GLM-5编程能力逼近Claude、豆包2.0价格低至0.6元/百万Token、可灵/Seedance让AI视频迈入生产级,元宝DAU破5000万——中国AI正集体超车。(239字)
|
6月前
|
数据采集 监控 机器人
实战!用Scrapy+Flask构建京东商品比价微信机器人
本项目是一个基于微信的京东智能比价机器人,集成Scrapy+Selenium爬虫、Flask API与itchat/Wechaty微信服务,支持商品搜索、实时比价、30天价格趋势分析、降价自动预警及收藏管理,全栈可部署(Docker+Nginx),助力用户省钱决策。(239字)
|
8月前
|
JSON 前端开发 Java
Spring Boot 中的 @RequestMapping 与快捷映射注解
`@RequestMapping` 是 Spring MVC 中用于映射 HTTP 请求路径与处理方法的核心注解,可标注在类或方法上。类上使用定义公共前缀,方法上指定具体路径和请求方式。常用属性包括 `value`(路径)、`method`(请求类型)、`produces`(响应类型)。Spring 还提供了 `@GetMapping`、`@PostMapping` 等快捷注解,语义更清晰,推荐优先使用。
|
传感器 人工智能 自动驾驶
九牧的“AI梦想曲”:卫浴场景进入到机器人时代
十年后的卫浴空间将不再仅仅是功能性场所,而是进化为个性化健康管理中枢。据DeepSeek预测,未来卫浴将引入全自动清洁与管理机器人、个性化健康管家等智能设备,成为家庭中的“第四生活伙伴”。九牧集团等企业已开始布局这一领域,启动AI马桶与家用机器人产业园建设,致力于打造智能卫浴产品,如机器人洗澡机、健康马桶等。这些创新不仅提升了用户体验,还标志着卫浴行业正迈向AI与机器人新时代,引领全球制造业变革。
522 1
|
存储 运维 Kubernetes
容器数据保护:基于容器服务 Kubernetes 版(ACK)备份中心实现K8s存储卷一键备份与恢复
阿里云ACK备份中心提供一站式容器化业务灾备及迁移方案,减少数据丢失风险,确保业务稳定运行。