222. Count Complete Tree Nodes

来源:互联网 发布:凯驰吸尘器 知乎 编辑:程序博客网 时间:2024/06/05 15:20

Given a complete binary tree, count the number of nodes.

Definition of a complete binary tree from Wikipedia:
In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h.
题目要求:给你一个完全二叉树,求总共的节点数。
原始方法:

int countNodes(TreeNode* root) {   if(!root) return 0;   return countNodes(root->left)+countNodes(root->right)+1;  }

这里的算法复杂度是: O(n)
因为这里的二叉树的特点是完全二叉树,因此可以根据这个特点进行优化。

/*eg1:有如下的一颗完全二叉树(左孩子满)                              o                            /   \                           o     o                            / \   / \                         o  o  o   o                        / \/ \/                       o  oo oo    如果完全二叉树的最后一行是满的,那么它左孩子和右孩子的高度应该是一样的。这里先求得   root根节点的高度h,如果右孩子的高度恰好为h-1,那么说明它的左孩子必定是满的(最后一行部空)。此时,可以确定它的左孩子的总节点数是2^h-1个,加上一个根节点,目前计数为2^h个。如下所示:                               x                            /    \                           x      o <- 新的根节点                           / \    / \                         x   x  o   o                        / \ / \/                       x  x x xo                        (x是已经计数的,o是未计数的)  此时,只再需要对它的右孩子进行计数即可。  以上讨论的是第一种情况,左孩子满的情况,还有可能左孩子不是满的,如下图所示。此时,右孩子必定也是一颗满的完全二叉树,但此时它的高度是h-2,故此时右孩子的节点总数为2^(h-1)-1, 此时加上根节点总数为2^(h-1)个。再对左孩子进行计数。 eg2:有如下的一颗完全二叉树(左孩子不满)                              o                            /   \                           o     o                            / \   / \                         o  o  o   o                        / \/                        o  oo 对右孩子进行计完树之后,再对左孩子计数。                              x                            /   \            新的根节点 ->   o     x                            / \   / \                         o  o  x   x                        / \/                        o  oo                        (x是已经计数的,o是未计数的)            */ int countNodes(TreeNode* root) {    // int h=height(root);    // return h<0?0:height(root->right)==h-1?(1<<h)+countNodes(root->right):(1<<h-1)+countNodes(root->left);      int nodes=0,h=height(root);      while(root!=nullptr)      {          if(height(root->right)==h-1)          {              nodes+=1<<h;              root=root->right;          }else          {              nodes+=1<<(h-1);              root=root->left;          }          h--;      }      return nodes;    }    int height(TreeNode* root)    {        return root==NULL?-1:1+height(root->left);    }

此时的时间复杂度是:O(logn)
原文来自StefanPochmann,自己翻译了下,加点注解。

0 0