zoukankan      html  css  js  c++  java
  • 二叉树的操作之统计二叉树中节点的个数

    一,问题描述

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

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

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

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

    二,算法分析

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

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

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

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

    //计算树中节点个数
        private int nubmerOfNodes(BinaryNode<T> root){
            int nodes = 0;
            if(root == null)
                return 0;
            else{
                nodes = 1 + nubmerOfNodes(root.left) + nubmerOfNodes(root.right);
            }
            return nodes;
        }
    

      

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

    //求二叉树的深度 
       public static int deep(Node node){ 
        int h1, h2;
           if(node == null) 
             {return 0; 
             }
           else{
       h1= deep(node.left);
       h2= deep(node.right);
         return (h1<h2)?h2+1:h1+1;
           }
           
       } 
    

      

    ②计算叶子结点的个数

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

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

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

    //计算树中叶结点的个数
        private int numberOfLeafs(BinaryNode<T> root){
            int nodes = 0;
            if(root == null)
                return 0;
            else if(root.left == null && root.right == null)
                return 1;
            else
                nodes = numberOfLeafs(root.left) + numberOfLeafs(root.right);
            return nodes;
        }
    

      

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

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

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

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

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

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

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

    //计算树中度为2的节点的个数--满节点的个数
        private int numberOfFulls(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 = numberOfFulls(root.right);
            else if(root.left != null && root.right == null)
                nodes = numberOfFulls(root.left);            
            else
                nodes = 1 + numberOfFulls(root.left) + numberOfFulls(root.right);
            return nodes;
        }
    

      

    对于二叉树而言,有一个公式:度为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
        }
    

      三,完整程序代码如下

    public class BinarySearchTree<T extends Comparable<? super T>> {
    
        private static class BinaryNode<T> {
            T element;
            BinaryNode<T> left;
            BinaryNode<T> right;
    
            public BinaryNode(T element) {
                this(element, null, null);
            }
    
            public BinaryNode(T element, BinaryNode<T> left, BinaryNode<T> right) {
                this.element = element;
                this.left = left;
                this.right = right;
            }
    
            public String toString() {
                return element.toString();
            }
        }
    
        private BinaryNode<T> root;
    
        public BinarySearchTree() {
            root = null;
        }
    
        public void insert(T ele) {
            root = insert(ele, root);// 每次插入操作都会'更新'根节点.
        }
    
        private BinaryNode<T> insert(T ele, BinaryNode<T> root) {
            if (root == null)
                return new BinaryNode<T>(ele);
            int compareResult = ele.compareTo(root.element);
            if (compareResult > 0)
                root.right = insert(ele, root.right);
            else if (compareResult < 0)
                root.left = insert(ele, root.left);
            else
                ;
            return root;
        }
    
        public int height() {
            return height(root);
        }
    
        private int height(BinaryNode<T> root) {
            if (root == null)
                return -1;// 叶子节点的高度为0,空树的高度为1
    
            return 1 + (int) Math.max(height(root.left), height(root.right));
        }
    
        public int numberOfNodes(BinarySearchTree<T> tree){
            return nubmerOfNodes(tree.root);
        }
        
        //计算树中节点个数
        private int nubmerOfNodes(BinaryNode<T> root){
            int nodes = 0;
            if(root == null)
                return 0;
            else{
                nodes = 1 + nubmerOfNodes(root.left) + nubmerOfNodes(root.right);
            }
            return nodes;
        }
        
        
        public int numberOfLeafs(BinarySearchTree<T> tree){
            return numberOfLeafs(tree.root);
        }
        //计算树中叶结点的个数
        private int numberOfLeafs(BinaryNode<T> root){
            int nodes = 0;
            if(root == null)
                return 0;
            else if(root.left == null && root.right == null)
                return 1;
            else
                nodes = numberOfLeafs(root.left) + numberOfLeafs(root.right);
            return nodes;
        }
        
        public int numberOfFulls(BinarySearchTree<T> tree){
            return numberOfFulls(tree.root);
            // return numberOfLeafs(tree.root) > 0 ? numberOfLeafs(tree.root)-1 : 0;// n(2)=n(0)-1
        }
        //计算树中度为2的节点的个数--满节点的个数
        private int numberOfFulls(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 = numberOfFulls(root.right);
            else if(root.left != null && root.right == null)
                nodes = numberOfFulls(root.left);            
            else
                nodes = 1 + numberOfFulls(root.left) + numberOfFulls(root.right);
            return nodes;
        }
        
        
        public static void main(String[] args) {
            BinarySearchTree<Integer> intTree = new BinarySearchTree<>();
            double averHeight = intTree.averageHeigth(1, 6, intTree);
            System.out.println("averageheight = " + averHeight);
            
            /*-----------All Nodes-----------------*/
            int totalNodes = intTree.numberOfNodes(intTree);
            System.out.println("total nodes: " + totalNodes);
            
            /*-----------Leaf Nodes-----------------*/
            int leafNodes = intTree.numberOfLeafs(intTree);
            System.out.println("leaf nodes: " + leafNodes);
            
            /*-----------Full Nodes-----------------*/
            int fullNodes = intTree.numberOfFulls(intTree);
            System.out.println("full nodes: " + fullNodes);
        }
    
        public double averageHeigth(int tree_numbers, int node_numbers, BinarySearchTree<Integer> tree) {
            int tree_height, totalHeight = 0;
            for(int i = 1; i <= tree_numbers; i++){
                int[] randomNumbers = C2_2_8.algorithm3(node_numbers);
                //build tree
                for(int j = 0; j < node_numbers; j++)
                {
                    tree.insert(randomNumbers[j]);
                    System.out.print(randomNumbers[j] + " ");
                }
                System.out.println();
                tree_height = tree.height();
                System.out.println("height:" + tree_height);
        
                totalHeight += tree_height;
    //            tree.root = null;//for building next tree
            }
        return (double)totalHeight / tree_numbers;
        }
    }
  • 相关阅读:
    Windows 程序员必备的知识和工具
    由级别和性格特征将程序员分类 看看你属于哪一种
    调试九法:软硬件错误的排查之道<书评>
    逆向反汇编代码推算C++的局部变量
    逆向分析一个完整的C++程序包含寄存器与参数传递详解
    1607:Unable to install InstallShield Scripting runtime
    Form的构造函数和Load事件的区别?
    "春运男子持刀强行劫走17张卧铺票" ....
    SQL SERVER 2005中的Case When用法
    SBO中各个版本的密码
  • 原文地址:https://www.cnblogs.com/chengpeng15/p/5910677.html
Copyright © 2011-2022 走看看