二叉树的操作之统计二叉树中节点的个数

简介:

一,问题描述

给定一颗二叉树,已知其根结点。

①计算二叉树所有结点的个数

②计算二叉树中叶子结点的个数

③计算二叉树中满节点(度为2)的个数

 

二,算法分析

找出各个问题的基准条件,然后采用递归的方式实现。

①计算二叉树所有结点的个数

1)当树为空时,结点个数为0,否则为根节点个数 加上 根的左子树中节点个数 再加上 根的右子树中节点的个数

借助遍历二叉树的思路,每访问一个结点,计数增1。因此,可使用类似于先序遍历的思路来实现,代码如下:

复制代码
 1     //计算树中节点个数
 2     private int nubmerOfNodes(BinaryNode<T> root){
 3         int nodes = 0;
 4         if(root == null)
 5             return 0;
 6         else{
 7             nodes = 1 + nubmerOfNodes(root.left) + nubmerOfNodes(root.right);
 8         }
 9         return nodes;
10     }
复制代码

计算树中节点个数的代码方法与计算树的高度的代码非常相似!

 

②计算叶子结点的个数

1)当树为空时,叶子结点个数为0

2)当某个节点的左右子树均为空时,表明该结点为叶子结点,返回1

3)当某个节点有左子树,或者有右子树时,或者既有左子树又有右子树时,说明该节点不是叶子结点,因此叶结点个数等于左子树中叶子结点个数 加上 右子树中叶子结点的个数

 

这种形式的递归返回的node值 是最外层方法的node。

复制代码
 1     //计算树中叶结点的个数
 2     private int numberOfLeafs(BinaryNode<T> root){
 3         int nodes = 0;
 4         if(root == null)
 5             return 0;
 6         else if(root.left == null && root.right == null)
 7             return 1;
 8         else
 9             nodes = numberOfLeafs(root.left) + numberOfLeafs(root.right);
10         return nodes;
11     }
复制代码

 

③计算满节点的个数(对于二叉树而言,满节点是度为2的节点)

满节点的基准情况有点复杂:

1)当树为空时,满节点个数为0

2)当树中只有一个节点时,满节点个数为0

3)当某节点只有左子树时,需要进一步判断左子树中是否存在满节点

4)当某节点只有右子树时,需要进一步判断右子树中是否存在满节点

5)当某节点即有左子树,又有右子树时,说明它是满结点。但是由于它的左子树或者右子树中可能还存在满结点,因此满结点个数等于该节点加上该节点的左子树中满结点的个数 再加上 右子树中满结点的个数。

代码如下:

复制代码
 1 //计算树中度为2的节点的个数--满节点的个数
 2     private int numberOfFulls(BinaryNode<T> root){
 3         int nodes = 0;
 4         if(root == null)
 5             return 0;
 6         else if(root.left == null && root.right == null)
 7             return 0;
 8         else if(root.left == null && root.right != null)
 9             nodes = numberOfFulls(root.right);
10         else if(root.left != null && root.right == null)
11             nodes = numberOfFulls(root.left);            
12         else
13             nodes = 1 + numberOfFulls(root.left) + numberOfFulls(root.right);
14         return nodes;
15     }
复制代码

 

对于二叉树而言,有一个公式:度为2的结点个数等于度为0的结点个数减去1。 即:n(2)=n(0)-1

故可以这样:

    private int numberOfFulls(BinaryNode<T> root){
        return numberOfLeafs(root) > 0 ? numberOfLeafs(root)-1 : 0;// n(2)=n(0)-1
    }

 

计算满节点个数的一些错误的方法:

错误方法一:

复制代码
    /*
     * 错误,忽略了如下情况:某个结点的左子树中存在满结点的情况
     *          6
     *       2
     *     1   3
     */
    private int numberOfFulls2(BinaryNode<T> root){
        int nodes = 0;
        if(root == null)
            return 0;
        else if(root.left == null || root.right == null)
            return 0;
        else if(root.left != null && root.right != null)
            nodes = 1 + numberOfFulls2(root.left) + numberOfFulls2(root.right);
        return nodes;
    }
复制代码

 

错误方法二:

复制代码
 1     //忽略了一种基准情况:只有一个节点的二叉树
 2     private int numberOfFulls3(BinaryNode<T> root){
 3         int nodes = 0;
 4         if(root == null)
 5             return 0;
 6         else if(root.left == null && root.right != null)
 7             nodes = numberOfFulls3(root.right);
 8         else if(root.left != null && root.right == null)
 9             nodes = numberOfFulls3(root.left);            
10         else
11             nodes = 1 + numberOfFulls3(root.left) + numberOfFulls3(root.right);
12         return nodes;
13     }
复制代码

 

三,完整程序代码如下:

复制代码
  1 import c2.C2_2_8;
  2 
  3 public class BinarySearchTree<T extends Comparable<? super T>> {
  4 
  5     private static class BinaryNode<T> {
  6         T element;
  7         BinaryNode<T> left;
  8         BinaryNode<T> right;
  9 
 10         public BinaryNode(T element) {
 11             this(element, null, null);
 12         }
 13 
 14         public BinaryNode(T element, BinaryNode<T> left, BinaryNode<T> right) {
 15             this.element = element;
 16             this.left = left;
 17             this.right = right;
 18         }
 19 
 20         public String toString() {
 21             return element.toString();
 22         }
 23     }
 24 
 25     private BinaryNode<T> root;
 26 
 27     public BinarySearchTree() {
 28         root = null;
 29     }
 30 
 31     public void insert(T ele) {
 32         root = insert(ele, root);// 每次插入操作都会'更新'根节点.
 33     }
 34 
 35     private BinaryNode<T> insert(T ele, BinaryNode<T> root) {
 36         if (root == null)
 37             return new BinaryNode<T>(ele);
 38         int compareResult = ele.compareTo(root.element);
 39         if (compareResult > 0)
 40             root.right = insert(ele, root.right);
 41         else if (compareResult < 0)
 42             root.left = insert(ele, root.left);
 43         else
 44             ;
 45         return root;
 46     }
 47 
 48     public int height() {
 49         return height(root);
 50     }
 51 
 52     private int height(BinaryNode<T> root) {
 53         if (root == null)
 54             return -1;// 叶子节点的高度为0,空树的高度为1
 55 
 56         return 1 + (int) Math.max(height(root.left), height(root.right));
 57     }
 58 
 59     public int numberOfNodes(BinarySearchTree<T> tree){
 60         return nubmerOfNodes(tree.root);
 61     }
 62     
 63     //计算树中节点个数
 64     private int nubmerOfNodes(BinaryNode<T> root){
 65         int nodes = 0;
 66         if(root == null)
 67             return 0;
 68         else{
 69             nodes = 1 + nubmerOfNodes(root.left) + nubmerOfNodes(root.right);
 70         }
 71         return nodes;
 72     }
 73     
 74     
 75     public int numberOfLeafs(BinarySearchTree<T> tree){
 76         return numberOfLeafs(tree.root);
 77     }
 78     //计算树中叶结点的个数
 79     private int numberOfLeafs(BinaryNode<T> root){
 80         int nodes = 0;
 81         if(root == null)
 82             return 0;
 83         else if(root.left == null && root.right == null)
 84             return 1;
 85         else
 86             nodes = numberOfLeafs(root.left) + numberOfLeafs(root.right);
 87         return nodes;
 88     }
 89     
 90     public int numberOfFulls(BinarySearchTree<T> tree){
 91         return numberOfFulls(tree.root);
 92         // return numberOfLeafs(tree.root) > 0 ? numberOfLeafs(tree.root)-1 : 0;// n(2)=n(0)-1
 93     }
 94     //计算树中度为2的节点的个数--满节点的个数
 95     private int numberOfFulls(BinaryNode<T> root){
 96         int nodes = 0;
 97         if(root == null)
 98             return 0;
 99         else if(root.left == null && root.right == null)
100             return 0;
101         else if(root.left == null && root.right != null)
102             nodes = numberOfFulls(root.right);
103         else if(root.left != null && root.right == null)
104             nodes = numberOfFulls(root.left);            
105         else
106             nodes = 1 + numberOfFulls(root.left) + numberOfFulls(root.right);
107         return nodes;
108     }
109     
110     
111     public static void main(String[] args) {
112         BinarySearchTree<Integer> intTree = new BinarySearchTree<>();
113         double averHeight = intTree.averageHeigth(1, 6, intTree);
114         System.out.println("averageheight = " + averHeight);
115         
116         /*-----------All Nodes-----------------*/
117         int totalNodes = intTree.numberOfNodes(intTree);
118         System.out.println("total nodes: " + totalNodes);
119         
120         /*-----------Leaf Nodes-----------------*/
121         int leafNodes = intTree.numberOfLeafs(intTree);
122         System.out.println("leaf nodes: " + leafNodes);
123         
124         /*-----------Full Nodes-----------------*/
125         int fullNodes = intTree.numberOfFulls(intTree);
126         System.out.println("full nodes: " + fullNodes);
127     }
128 
129     public double averageHeigth(int tree_numbers, int node_numbers, BinarySearchTree<Integer> tree) {
130         int tree_height, totalHeight = 0;
131         for(int i = 1; i <= tree_numbers; i++){
132             int[] randomNumbers = C2_2_8.algorithm3(node_numbers);
133             //build tree
134             for(int j = 0; j < node_numbers; j++)
135             {
136                 tree.insert(randomNumbers[j]);
137                 System.out.print(randomNumbers[j] + " ");
138             }
139             System.out.println();
140             tree_height = tree.height();
141             System.out.println("height:" + tree_height);
142     
143             totalHeight += tree_height;
144 //            tree.root = null;//for building next tree
145         }
146     return (double)totalHeight / tree_numbers;
147     }
148 }
复制代码

相关文章
|
3月前
|
Java C++ Python
leetcode-222:完全二叉树的节点个数
leetcode-222:完全二叉树的节点个数
14 0
|
4月前
二叉树查找值为x的结点、树的高度、第k层结点个数的代码实现
二叉树查找值为x的结点、树的高度、第k层结点个数的代码实现
|
6月前
|
算法 C语言
【数据结构】二叉树的节点数,叶子数,第K层节点数,高度,查找x节点,判断是否为完全二叉树等方法【上】
文章目录 一、二叉数的结构体 二、构建二叉树,供后续测试使用 三、二叉树销毁 四、构建节点 五、二叉树的高度: 1.代码: 2.测试结果: 二叉树节点个数 1.代码: 2.测试结果:
|
6月前
|
算法 DataX C语言
【数据结构】二叉树的节点数,叶子数,第K层节点数,高度,查找x节点,判断是否为完全二叉树等方法【下】
六、二叉树叶子节点个数 1.代码: 2.测试结果: 七、二叉树第k层节点个数 1.代码: 2.测试结果: 八、二叉树查找值为x的节点 1.代码: 2.测试结果: 九、判断二叉树是否是完全二叉树 1.代码: 2.测试结果: 十、补充:队列代码 Queue.h Queue.c
|
3月前
|
存储 算法
算法题解-完全二叉树的节点个数
算法题解-完全二叉树的节点个数
|
4月前
|
算法
二叉树的结点个数、叶子结点个数的代码实现<分治算法>
二叉树的结点个数、叶子结点个数的代码实现<分治算法>
|
8月前
|
存储 算法
算法训练Day17|● 104.二叉树的最大深度 559.n叉树的最大深度● 111.二叉树的最小深度● 222.完全二叉树的节点个数
算法训练Day17|● 104.二叉树的最大深度 559.n叉树的最大深度● 111.二叉树的最小深度● 222.完全二叉树的节点个数
|
9月前
|
算法
【数据结构与算法】二叉树的深度,节点数,第k层的节点数,遍历,二叉树叶节点的个数
【数据结构与算法】二叉树的深度,节点数,第k层的节点数,遍历,二叉树叶节点的个数
121 0
|
10月前
|
算法 安全
二叉树的基本操作(如何计算二叉树的结点个数,二叉树的高度)
二叉树的基本操作(如何计算二叉树的结点个数,二叉树的高度)
175 0
|
10月前
|
Python
Python实现统计二叉树叶子结点个数
Python实现统计二叉树叶子结点个数
138 0