二叉树k层的叶子结点个数

文章目录

  • 1 题目
  • 2 思路
    • 2.1 思路1
    • 2.2 思路2
  • 3 代码实现
    • 3.1 思路1
    • 3.2 思路2
    • 3.3 完整的代码案例

1 题目

假设二叉树采用二叉链表存储结构,设计一个算法求其指定的第k层(k>1,跟是第1层)的叶子结点个数。

2 思路

2.1 思路1

设置一个全局变量记录某层叶子结点个数,前序遍历二叉树,并在遍历的过程中记录结点的层数。

2.2 思路2

层序遍历二叉树,记录某层的二叉树叶子结点个数。没有目标层时,让该层结点的孩子结点入队;到达目标层时,不再让该层的孩子结点入队,统计队中(该层)叶子结点的个数。

  • 具体流程
    • 设置两个指针分别指该层的最后一个结点lastNode(初始为根结点)和下一层的最后一个非叶结点newNode。
    • 每遍历到结点的左/右孩子为非叶结点时,把newNode更新为当前结点的左/右孩子;
    • 当遍历的结点为该层的最后结点时,把lastNode更新为最新的newNode。

3 代码实现

二叉树的存储结构:

template <typename T>
class BiTNode {
public:T data;BiTNode* left;BiTNode* right;BiTNode():data(NULL),left(NULL),right(NULL){};
};template <>
class BiTNode<int> {
public:int data;BiTNode* left;BiTNode* right;BiTNode() : data(0), left(nullptr), right(nullptr) {}BiTNode(int x) : data(x), left(nullptr), right(nullptr) {}BiTNode(int x, BiTNode *left, BiTNode *right) : data(x), left(left), right(right) {}
};template <>
class BiTNode<char> {
public:char data;BiTNode* left;BiTNode* right;BiTNode() : data('\0'), left(nullptr), right(nullptr) {}BiTNode(char x) : data(x), left(nullptr), right(nullptr) {}BiTNode(char x, BiTNode *left, BiTNode *right) : data(x), left(left), right(right) {}
};

3.1 思路1

template <typename T>
void calLevelLeaf(BiTNode<T>* root, int level, int k){if(level < k){if(root->left != nullptr) calLevelLeaf(root->left, level+1, k);if(root->right != nullptr) calLevelLeaf(root->right, level+1, k);}else if(level == k && root->left == nullptr && root->right == nullptr){leafNum++;}
} template <typename T>
int getLevelLeaf(BiTNode<T>* root, int k){calLevelLeaf(root, 1,  k);return leafNum;
}

3.2 思路2

template <typename T>
int getLevelLeaf2(BiTNode<T>* root, int k){deque<BiTNode<T>*> q;//双端队列BiTNode<T> *newNode = nullptr, *lastNode = root;  int level = 1;//层数int leafNum = 0;//该层的叶子结点个数q.push_back(root);while(!q.empty()){BiTNode<T>* p;if(level == k){while(!q.empty()){p = q.front();q.pop_front();if(p->left == nullptr && p->right == nullptr){leafNum++;}}break;}else{p = q.front();q.pop_front();if(p->left != nullptr){q.push_back(p->left);newNode = p->left;}if(p->right != nullptr){q.push_back(p->right);newNode = p->right;}if(lastNode == p){lastNode = newNode;level += 1;}}}return leafNum;
}

3.3 完整的代码案例

#include <iostream>
#include <stack>
#include <deque>
#include <queue>
using namespace std;template <typename T>
class BiTNode {
public:T data;BiTNode* left;BiTNode* right;BiTNode():data(NULL),left(NULL),right(NULL){};
};template <>
class BiTNode<int> {
public:int data;BiTNode* left;BiTNode* right;BiTNode() : data(0), left(nullptr), right(nullptr) {}BiTNode(int x) : data(x), left(nullptr), right(nullptr) {}BiTNode(int x, BiTNode *left, BiTNode *right) : data(x), left(left), right(right) {}
};template <>
class BiTNode<char> {
public:char data;BiTNode* left;BiTNode* right;BiTNode() : data('\0'), left(nullptr), right(nullptr) {}BiTNode(char x) : data(x), left(nullptr), right(nullptr) {}BiTNode(char x, BiTNode *left, BiTNode *right) : data(x), left(left), right(right) {}
};template <typename T>
void createBiTNode(BiTNode<T>** treeNode, deque<T>dataDeq) {//层序遍历建立二叉树//特殊处理根结点T data;data = dataDeq.front();dataDeq.pop_front();BiTNode<T> * node = new BiTNode<T>();*treeNode = node;(*treeNode)->data = data;deque<BiTNode<T>**> nodeDeq;//用于层序建立树时访问双亲节点nodeDeq.push_back(treeNode);int index = 2;//用于判定左右孩子(左偶,右奇)while (!dataDeq.empty()){//当数据节点非空时,进行建树BiTNode<T>** nodeParent = nodeDeq.front();nodeDeq.pop_front();for(int i = 0; i < 2;i++){data = dataDeq.front();dataDeq.pop_front();if(data == '#'){//适用于char//if(data == -1){//适用于intif(index%2 == 0) (*nodeParent)->left = nullptr;else (*nodeParent)->right = nullptr;}else{BiTNode<T> * node = new BiTNode<T>();node->data = data;if(index%2 == 0){(*nodeParent)->left = node;nodeDeq.push_back(&(*nodeParent)->left);}else{(*nodeParent)->right = node;nodeDeq.push_back(&(*nodeParent)->right);}}index++;}}
}template <>
void createBiTNode<char>(BiTNode<char>** treeNode, deque<char>dataDeq) {//层序遍历建立二叉树//特殊处理根结点char data;data = dataDeq.front();dataDeq.pop_front();BiTNode<char> * node = new BiTNode<char>();*treeNode = node;(*treeNode)->data = data;deque<BiTNode<char>**> nodeDeq;//用于层序建立树时访问双亲节点nodeDeq.push_back(treeNode);int index = 2;//用于判定左右孩子(左偶,右奇)while (!dataDeq.empty()){//当数据节点非空时,进行建树BiTNode<char>** nodeParent = nodeDeq.front();nodeDeq.pop_front();for(int i = 0; i < 2;i++){data = dataDeq.front();dataDeq.pop_front();if(data == '#'){if(index%2 == 0) (*nodeParent)->left = nullptr;else (*nodeParent)->right = nullptr;}else{BiTNode<char> * node = new BiTNode<char>();node->data = data;if(index%2 == 0){(*nodeParent)->left = node;nodeDeq.push_back(&(*nodeParent)->left);}else{(*nodeParent)->right = node;nodeDeq.push_back(&(*nodeParent)->right);}}index++;}}
}template <>
void createBiTNode<int>(BiTNode<int>** treeNode, deque<int>dataDeq) {//层序遍历建立二叉树//特殊处理根结点char data;data = dataDeq.front();dataDeq.pop_front();BiTNode<int> * node = new BiTNode<int>();*treeNode = node;(*treeNode)->data = data;deque<BiTNode<int>**> nodeDeq;//用于层序建立树时访问双亲节点nodeDeq.push_back(treeNode);int index = 2;//用于判定左右孩子(左偶,右奇)while (!dataDeq.empty()){//当数据节点非空时,进行建树BiTNode<int>** nodeParent = nodeDeq.front();nodeDeq.pop_front();for(int i = 0; i < 2;i++){data = dataDeq.front();dataDeq.pop_front();if(data == -1){if(index%2 == 0) (*nodeParent)->left = nullptr;else (*nodeParent)->right = nullptr;}else{BiTNode<int> * node = new BiTNode<int>();node->data = data;if(index%2 == 0){(*nodeParent)->left = node;nodeDeq.push_back(&(*nodeParent)->left);}else{(*nodeParent)->right = node;nodeDeq.push_back(&(*nodeParent)->right);}}index++;}}
}template <typename T>
void inOrder(BiTNode<T>* treeNode){if(treeNode){inOrder(treeNode->left);cout<<treeNode->data<<" ";inOrder(treeNode->right);}
}template <typename T>
void preOrder(BiTNode<T>* treeNode){if(treeNode){cout<<treeNode->data<<" ";preOrder(treeNode->left);preOrder(treeNode->right);}
}template <typename T>
void postOrder(BiTNode<T>* treeNode){if(treeNode){postOrder(treeNode->left);postOrder(treeNode->right);cout<<treeNode->data<<" ";}
}template <typename T>
void preOrder2(BiTNode<T>* treeNode){stack<BiTNode<T>*> s;BiTNode<T>* p = treeNode;while(p || !s.empty()){if(p){cout<<p->data<<" ";s.push(p);p = p->left;}else{p = s.top();s.pop();p = p->right;}}
}template <typename T>
void inOrder2(BiTNode<T>* treeNode){stack<BiTNode<T>*> s;BiTNode<T>* p = treeNode;while(p || !s.empty()){if(p){s.push(p);p = p->left;}else{p = s.top();cout<<p->data<<" ";s.pop();p = p->right;}}
}template <typename T>
void postOrder2(BiTNode<T>* treeNode){stack<BiTNode<T>*> s;BiTNode<T> *p = treeNode, *r = nullptr;while(p || !s.empty()){if(p){s.push(p);p = p->left;}else{p = s.top();if(p->right && p->right != r){//有右孩子且没有访问过p = p->right;}else{cout<<p->data<<" ";s.pop();r = p;p = nullptr;}}}
}template <typename T>
void levelOrder(BiTNode<T>* treeNode) {queue<BiTNode<T>*> nodeQue;BiTNode<T>* p = treeNode;nodeQue.push(p);while(!nodeQue.empty()){p = nodeQue.front();nodeQue.pop();cout<<p->data<<" ";if(p->left) nodeQue.push(p->left);if(p->right) nodeQue.push(p->right);}
}int leafNum = 0;template <typename T>
void calLevelLeaf(BiTNode<T>* root, int level, int k){if(level < k){if(root->left != nullptr) calLevelLeaf(root->left, level+1, k);if(root->right != nullptr) calLevelLeaf(root->right, level+1, k);}else if(level == k && root->left == nullptr && root->right == nullptr){leafNum++;}
} template <typename T>
int getLevelLeaf(BiTNode<T>* root, int k){calLevelLeaf(root, 1,  k);return leafNum;
}template <typename T>
int getLevelLeaf2(BiTNode<T>* root, int k){deque<BiTNode<T>*> q;//双端队列BiTNode<T> *newNode = nullptr, *lastNode = root;  int level = 1;//层数int leafNum = 0;//该层的叶子结点个数q.push_back(root);while(!q.empty()){BiTNode<T>* p;if(level == k){while(!q.empty()){p = q.front();q.pop_front();if(p->left == nullptr && p->right == nullptr){leafNum++;}}break;}else{p = q.front();q.pop_front();if(p->left != nullptr){q.push_back(p->left);newNode = p->left;}if(p->right != nullptr){q.push_back(p->right);newNode = p->right;}if(lastNode == p){lastNode = newNode;level += 1;}}}return leafNum;
}int main() {//使用字符串//deque<char> treeVec{'a', 'b', 'c', 'd', 'e', '#', '#'};//deque<char> treeVec{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', '#', '#','i','#','#','k','l'};deque<char> treeVec{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', '#', 'i', 'j','#','#','k','l','m','n','#','#','o','#','#','p','#','#'};BiTNode<char>* tree = new BiTNode<char>();createBiTNode(&tree, treeVec);//使用数值
//    deque<int> treeVec{1, 2, 3, 4, 5, -1, -1};
//    BiTNode<int>* tree = new BiTNode<int>();
//    createBiTNode(&tree, treeVec);//遍历树//inOrder(tree);//cout<<endl;printf("%d", getLevelLeaf2(tree, 5));//tree,4return 0;    
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/194119.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Oracle(2-6) Backup and Recovery Overview

文章目录 一、基础知识1、Categories of Failures 故障类别2、Causes of Statement Failures 语句失败的原因故障情况Resolutions 决议 3、User Process Failures 用户进程失败故障情况Resolutions 决议 4、Possible User Errors 用户错误类型故障情况Resolutions 决议 5、Inst…

实验6 二叉树操作

0x01 实验目的 掌握二叉树的基本概念&#xff0c;二叉树的存储结构使用链表。 0x02 实验内容 输入一个完全二叉树的层次遍历字符串&#xff0c;创建这个二叉树&#xff0c;输出这个二叉树的前序遍历字符串、中序遍历字符串、后序遍历字符串、结点数目、二叉树高度(上述每一个…

什么是缓存雪崩、缓存击穿、缓存穿透?

一、缓存雪崩 当某一个时刻出现大规模的缓存失效的情况&#xff0c;那么就会导致大量的请求直接打在数据库上面&#xff0c;导致数据库压力巨大&#xff0c;如果在高并发的情况下&#xff0c;可能瞬间就会导致数据库宕机。这时候如果运维马上又重启数据库&#xff0c;马上又会…

计算UDP报文CRC校验的总结

概述 因公司项目需求&#xff0c;遇到需要发送带UDP/IP头数据包的功能&#xff0c;经过多次尝试顺利完成&#xff0c;博文记录以备忘。 环境信息 操作系统 ARM64平台的中标麒麟Kylin V10 工具 tcpdump、wireshark、vscode 原理 请查看大佬的博文 UDP伪包头定义&#x…

关于Maxscript你了解多少?

MAXScript是Autodesk 3dMax的内置脚本语言。MAXScript为3dMax用户提供了以下功能&#xff1a; 编写程序使用的大部分方面的脚本&#xff0c;如建模、动画、材质、渲染等。 通过命令行侦听器窗口以交互方式控制程序。 在自定义实用工具面板卷展栏或无模式窗口中打包脚本&…

MQ - 消息系统

消息系统 1、消息系统的演变 在大型系统中&#xff0c;会需要和很多子系统做交互&#xff0c;也需要消息传递&#xff0c;在诸如此类系统中&#xff0c;你会找到源系统&#xff08;消息发送方&#xff09;和 目的系统&#xff08;消息接收方&#xff09;。为了在这样的消息系…

力扣二叉树--第三十七天

前言 废话不多说&#xff0c;能学到东西&#xff01;功不唐捐&#xff01; 内容 一、二叉搜索树的最小绝对差 530. 二叉搜索树的最小绝对差 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等…

JAVA代码优化:Spring中redis的工具类

基于Spring框架和Redis的缓存工具类。该类提供了一系列方法用于操作Redis缓存&#xff0c;包括设置缓存对象、设置缓存超时时间、获取缓存对象、删除对象、缓存List、Set、Map等操作。通过这些方法可以方便地对Redis进行数据缓存和读取操作。同时&#xff0c;该类使用了Spring的…

【PyTorch】数据集

文章目录 1. 创建数据集1.1. 直接继承Dataset类1.2. 使用TensorDataset类 2. 数据集的划分3. 加载数据集4. 将数据转移到GPU 1. 创建数据集 主要是将数据集读入内存&#xff0c;并用Dataset类封装。 1.1. 直接继承Dataset类 必须要重写__getitem__方法&#xff0c;用于根据索…

【代码随想录算法训练营-第二天】【数组】977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

977.有序数组的平方 看完思路后一遍AC 思路剖析&#xff1a; 因为提到了时间复杂度为O(n)&#xff0c;自然想到只能遍历一遍又因为只规定了时间复杂度&#xff0c;但是没有规定空间复杂度&#xff0c;所以可以考虑在定义一个数组【这一步没有考虑出来&#xff0c;是看了思路的…

数据结构和算法-哈夫曼树以相关代码实现

文章目录 总览带权路径长度哈夫曼树的定义哈夫曼树的构造法1法2 哈夫曼编码英文字母频次总结实验内容&#xff1a; 哈夫曼树一、上机实验的问题和要求&#xff08;需求分析&#xff09;&#xff1a;二、程序设计的基本思想&#xff0c;原理和算法描述&#xff1a;三、调试和运行…

Matter学习笔记(3)——交互模型

一、简介 1.1 交互方式 交互模型层定义了客户端和服务器设备之间可以执行哪些交互。发起交互的节点称为发起者&#xff08;通常为客户端设备&#xff09;&#xff0c;作为交互的接收者的节点称为目标&#xff08;通常为服务器设备&#xff09;。 节点通过以下方式进行交互&a…

Spring Initial 脚手架国内镜像地址

官方的脚手架下载太慢了&#xff0c;并且现在没有了Java8的选项&#xff0c;所以找到国内的脚手架镜像地址&#xff0c;推荐给大家。 首先说官方的脚手架 官方的脚手架地址为&#xff1a; https://start.spring.io/ 但是可以看到&#xff0c;并没有了Java8的选项。 所以推荐…

3dMax拼图生成工具Puzzle2D使用教程

Puzzle2D for 3dsMax拼图生成工具使用教程 Puzzle2D简介&#xff1a; 2D拼图随机生成器&#xff08;英文&#xff1a;Puzzle2D&#xff09; &#xff0c;是一款由#沐风课堂#用MAXScript脚本语言开发的3dsMax建模小工具&#xff0c;可以随机创建2D可编辑样条线拼图图形。可批量…

【tensorflow学习-选择动作】 学习tensorflow代码调用过程

a actor.choose_action(s) def choose_action(self, s):s s[np.newaxis, :]return self.sess.run(self.action, {self.s: s}) # get probabilities for all actions输入&#xff1a;s 输出&#xff1a;self.sess.run(self.action, {self.s: s}) &#xff1a;a

解决:UnboundLocalError: local variable ‘js’ referenced before assignment

解决&#xff1a;UnboundLocalError: local variable ‘js’ referenced before assignment 文章目录 解决&#xff1a;UnboundLocalError: local variable js referenced before assignment背景报错问题报错翻译报错位置代码报错原因解决方法今天的分享就到此结束了 背景 在使…

MongoDB的原子性和多文档事务处理

原子性和事务处理是数据库操作的核心&#xff0c;保证了数据的准确性。依据数据库原子性&#xff0c;数据库和使用数据库的人员定义事务处理的方式。本文依据Mongodb的官方文档&#xff0c;整理Mongodb数据库的原子性和事务处理方法。 Mongodb的原子操作 Mongodb中&#xff0c…

实战案例:chatglm3 基础模型多轮对话微调

chatglm3 发布了&#xff0c;这次还发了base版本的模型&#xff0c;意味着我们可以基于这个base模型去自由地做SFT了。 本项目实现了基于base模型的SFT。 base模型 https://huggingface.co/THUDM/chatglm3-6b-base由于模型较大&#xff0c;建议离线下载后放在代码目录&#…

OSG编程指南:专栏内容介绍及目录

1、专栏介绍 OpenSceneGraph&#xff08;OSG&#xff09;场景图形系统是一个基于工业标准 OpenGL 的软件接口&#xff0c;它让程序员能够更加快速、便捷地创建高性能、跨平台的交互式图形程序。本专栏基于 OSG 3.6.5版本进行源码的编写及扩展&#xff0c;也通用于其他OSG版本的…