欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

已知一棵完全二叉树,求其节点的个数

程序员文章站 2022-03-03 09:34:17
...

已知一棵完全二叉树,求其节点的个数
要求:时间复杂度低于O(N),N为这棵树的节点个数

思路

满二叉树:层数为ll,节点个数为2l12^l-1

  • 从根节点出发,一路遍历其左孩子可以得到该二叉树的高度hh
  • 从该二叉树的右孩子节点开始遍历其左孩子可以得到该部分二叉树可以到达的最深的层数,如果可以到达hh层,那么左子树是满二叉树,可以得到节点数,右子树不是满二叉树,对其进行递归;如果右子树不能到达hh层,那么右子树是满二叉树,可以得到节点数,对左子树进行递归。

代码

package BinaryTree;

public class CompleteTreeNodeNumber {

    public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int data) {
            this.value = data;
        }
    }

    public static int NodeNumber(Node head){
        if (head==null){
            return 0;
        }
        return bs(head,1,mostLeftLevel(head,1));
    }

    //level:当前节点所在的层,h:所求二叉树的总层数
    public static int bs(Node head,int level,int h){
        if (level==h){
            return 1;
        }
        if (mostLeftLevel(head.right,level+1)==h){
            //右子树到达h层,则左子树是满的,层数是h-level
            return (1<<(h-level))+bs(head.right,level+1,h);
        }else {//右子树没有到达h层,则右子树是满的但层数是h-level-1
            return (1<<(h-level-1))+bs(head.left,level+1,h);
        }
    }

	//当前节点最左边节点能到达的深度,level:当前节点所在的深度
    public static int mostLeftLevel(Node head,int level){
        while (head!=null){
            level++;
            head=head.left;
        }
        return level-1;
    }

    public static void main(String[] args) {
        Node head = new Node(1);
        head.left = new Node(2);
        head.right = new Node(3);
        head.left.left = new Node(4);
        head.left.right = new Node(5);
        head.right.left = new Node(6);
        System.out.println(NodeNumber(head));
    }
}