求二叉树中第K层结点的个数
一,问题描述
构建一棵二叉树(不一定是二叉查找树),求出该二叉树中第K层中的结点个数(根结点为第0层)
二,二叉树的构建
定义一个BinaryTree类来表示二叉树,二叉树BinaryTree 又是由各个结点组成的,因此需要定义一个结点类BinaryNode,BinaryNode作为BinaryTree的内部类。
此外,在BinaryTree中需要一定一个BinaryNode属性来表示树的根结点。
public class BinaryTree<T extends Comparable<? super T>> {
private static class BinaryNode<T>{
T element;
BinaryNode<T> left;
BinaryNode<T> right;
public BinaryNode(T element) {
this.element = element;
left = right = null;
}
public BinaryNode(T element, BinaryNode<T> left, BinaryNode<T> right){
this.element = element;
this.left = left;
this.right = right;
}
}
private BinaryNode<T> root;
//other code.....
第一行是二叉树类的定义,第三行是结点类的定义,第20行是二叉树根的定义。
三,求解第K层结点个数的算法实现
感觉对二叉树中的许多操作都可以用递归来实现。因此,二叉树是理解递归一个好实例。比如,二叉树的操作之统计二叉树中节点的个数 和 二叉树的先序遍历和后序遍历的应用--输出文件和统计目录大小
求第K层结点的个数也可以用递归来实现:
①若二叉树为空或者K小于0,返回0
②若K等于0,第0层就是树根,根只有一个,返回1
③若K大于0,返回左子树中第K-1层结点个数 加上 右子树中第K-1层结点的个数
因为,第K层结点,相对于根的左子树 和 右子树 而言,就是第K-1层结点
其实,这是有改进的地方:对于K<0的情形,准确地说:它只是一个非法输入,而不是递归的结束条件(基准条件)。可以看出,①不要把非法输入与递归的基准条件混淆,②把非法输入的判断放到递归中判断的开销是很大的。因为每进行一次递归就需要进行一次非法输入判断。而如果在开始就把非法输入过滤掉,在递归过程中就不会存在每一次递归就判断一次非法输入了。
递归的基准条件只有两个:
1) k==0 当递归到K==0时,说明:第K层是有结点的
2) root==null 当递归到root==null时,说明:第K层没有结点
因此,可以进一步将代码改进如下:这样,不需要在每次递归的过程中还可能附加一次 k<0 的判断
/**
*
* @param k
* @return 二叉树中第K层结点的个数(根位于第0层)
*/
public int k_nodes(int k){
if(k < 0)
return 0;
return k_nodes(root, k);
}
private int k_nodes(BinaryNode<T> root, int k){
if(root == null)
return 0;
if(k == 0)
return 1;//根结点
else
return k_nodes(root.left, k-1) + k_nodes(root.right, k-1);
}
可参考:按层打印二叉树--每行打印一层 来测试每一层是否有正确的结点个数。
四,代码实现
public class BinaryTree<T extends Comparable<? super T>> {
private static class BinaryNode<T>{
T element;
BinaryNode<T> left;
BinaryNode<T> right;
public BinaryNode(T element) {
this.element = element;
left = right = null;
}
}
private BinaryNode<T> root;
/**
* 向二叉树中插入一个元素
* @param element
*/
public void insert(T element){
root = insert(root, element);
}
private BinaryNode<T> insert(BinaryNode<T> root, T element){
if(root == null)
return new BinaryNode<T>(element);
int r = (int)(2*Math.random());
//随机地将元素插入到左子树 或者 右子树中
if(r==0)
root.left = insert(root.left, element);
else
root.right = insert(root.right, element);
return root;
}
/**
*
* @param k
* @return 二叉树中第K层结点的个数(根位于第0层)
*/
public int k_nodes(int k){
return k_nodes(root, k);
}
private int k_nodes(BinaryNode<T> root, int k){
if(root == null || k < 0)
return 0;
if(k == 0)
return 1;//根结点
else
return k_nodes(root.left, k-1) + k_nodes(root.right, k-1);
}
public static void main(String[] args) {
BinaryTree<Integer> tree = new BinaryTree<>();
int[] ele = C2_2_8.algorithm1(4);//构造一个随机数组,数组元素的范围为[1,4]
for (int i = 0; i < ele.length; i++) {
tree.insert(ele[i]);
}
int k_nodes = tree.k_nodes(2);//第二层
int k_nodes2 = tree.k_nodes(-1);//第-1层
int k_nodes3 = tree.k_nodes(0);
int k_nodes4 = tree.k_nodes(1);
int k_nodes5 = tree.k_nodes(4);//若超过了树的高度,结果为0
System.out.println(k_nodes);
System.out.println(k_nodes2);
System.out.println(k_nodes3);
System.out.println(k_nodes4);
System.out.println(k_nodes5);
}
}
关于 C2_2_8类,参考:随机序列生成算法---生成前N个整数的一组随机序列
五,参考资料
http://blog.csdn.net/luckyxiaoqiang/article/details/7518888
求二叉树中第K层结点的个数的更多相关文章
- 二叉树(9)----打印二叉树中第K层的第M个节点,非递归算法
1.二叉树定义: typedef struct BTreeNodeElement_t_ { void *data; } BTreeNodeElement_t; typedef struct BTree ...
- 六:二叉树中第k层节点个数与二叉树叶子节点个数
二叉树中第k层节点个数 递归解法: (1)假设二叉树为空或者k<1返回0 (2)假设二叉树不为空而且k==1.返回1 (3)假设二叉树不为空且k>1,返回左子树中k-1层的节点个数与右子树 ...
- 求二叉树第K层的节点个数+求二叉树叶子节点的个数
size_t _FindLeafSize(Node* root) //求二叉树叶子节点的个数 { //static size_t count = 0; if ...
- LeetCode OJ:Kth Smallest Element in a BST(二叉树中第k个最小的元素)
Given a binary search tree, write a function kthSmallest to find the kth smallest element in it. Not ...
- [LeetCode] Closest Leaf in a Binary Tree 二叉树中最近的叶结点
Given a binary tree where every node has a unique value, and a target key k, find the value of the n ...
- 求数列中第K大的数
原创 利用到快速排序的思想,快速排序思想:https://www.cnblogs.com/chiweiming/p/9188984.html array代表存放数列的数组,K代表第K大的数,mid代表 ...
- [LeetCode] Second Minimum Node In a Binary Tree 二叉树中第二小的结点
Given a non-empty special binary tree consisting of nodes with the non-negative value, where each no ...
- 求n!中因子k的个数
思路: 求n的阶乘某个因子k的个数,如果n比较小,可以直接算出来,但是如果n很大,此时n!超出了数据的表示范围,这种直接求的方法肯定行不通.其实n!可以表示成统一的方式. n!=(km)*(m!)*a ...
- hdu4587 Two Nodes 求图中删除两个结点剩余的连通分量的数量
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4587 题目给了12000ms,对于tarjan这种O(|V|+|E|)复杂度的算法来说,暴力是能狗住的 ...
随机推荐
- FastDFS教程Ⅰ-文件服务器安装与Nginx配置
1.简介 FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载均衡的问题.特别适合以文件为载 ...
- Scrapy的日志等级和请求传参
日志等级 日志信息: 使用命令:scrapy crawl 爬虫文件 运行程序时,在终端输出的就是日志信息: 日志信息的种类: ERROR:一般错误: WARNING:警告: INFO:一般的信息: ...
- Jmeter(四)_16个逻辑控制器详解
循环控制器: 指定其子节点运行的次数,可以使用具体的数值,也可以设置为变量 1:勾选永远:表示一直循环下去 2:如果同时设置了线程组的循环次数和循环控制器的循环次数,那循环控制器的子节点运行的次数为两 ...
- 如何在百度云虚拟机中配置thinkphp5,并且url去掉index.php
第一步:将public目录下的index.php移到和public同级目录下,[或者直接在public同级目录下新建一个index.php] 第二步:那么这个新的index.php文件的内容如下: & ...
- Spark RDD深度解析-RDD计算流程
Spark RDD深度解析-RDD计算流程 摘要 RDD(Resilient Distributed Datasets)是Spark的核心数据结构,所有数据计算操作均基于该结构进行,包括Spark ...
- jedispool资源释放
我的天啊,这几天要被jedis逼疯了,网上好多资料并没有介绍jedis链接释放不了的方法,我确定他们那些老人肯定知道都,就是不说,你们说气人不.还有要吐槽哈jedis源码开发的那些家伙,怎么写的代码, ...
- 2D开机动画
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name ...
- [转帖] k8s dashboard 的创建 升级 以及 admin token的创建和简单使用.
Kubernetes Dashboard中的身份认证详解 https://jimmysong.io/posts/kubernetes-dashboard-upgrade/ Thu Nov 2, 201 ...
- 深入理解ajax系列第六篇——头部信息
前面的话 每个HTTP请求和响应都会带有相应的头部信息,其中有的对开发人员有用.XHR对象提供了操作头部信息的方法.本文将详细介绍HTTP的头部信息 默认信息 默认情况下,在发送XHR请求的同时,还会 ...
- poj3468 A Simple Problem with Integers(线段树/树状数组)
Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...