首先明确一下完全二叉树的定义:
在一棵二叉树中,除最后一层外,若其余层都是满的,并且最后一层或者是满的,或者是在右边缺少连续若干节点,则此二叉树为完全二叉树(Complete Binary Tree).
完全二叉树是由完美二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的完美二叉树中编号从1至n的结点一一对应时称之为完全二叉树.满二叉树是
关于满二叉树的定义我迷惑了好久,最后才得知原来国内外对于满二叉树的定义并不一样,国内满二叉树的定义是一棵深度为k,具有2^k - 1个节点的二叉树;而国外对于二叉树的定义则是树中除了叶子节点,每个节点都有两个子节点的二叉树.为了避免歧义,这里采用浙大数据结构中的说法「完美二叉树」来表示国内版的满二叉树.
根据定义,我来证明一下如何计算二叉树左子树的规模.
假设有一棵深度为h的完美二叉树,那么它的第k层的节点个数是2^(k - 1),那么总节点数是2^h - 1,最后一层节点数是2^(h - 1),除去最后一层的节点个数是2^(h -1) - 1. 如果又一棵总节点数为N的完全二叉树,设高度为H,到第H层的完美二叉树一共有2^H - 1个节点.设最底层有x个节点,那么有以下方程
2^H - 1 + x = N
H = (int)log2(N + 1)
因为已知了节点总数N,所以算出H后就可以算出最底层一共有多少个节点.
然后,我们需要在算一下左子树的节点数,H层的总节点数是2^H - 1那么左节点也就是少了一层,2^(H-1) - 1.这时候就有一个问题,x个节点并不一定全是位于左子树,所以需要进行比较,x最大数目是2 ^ (H - 1) ,所以最后要做一个判断,x = min(x,2^(H-1)),左子树的个数应该是2^(H-1)-1 + x.
代码
1 | // |
然后再写一个判断完全二叉树的算法.同样根据二叉树的性质,显然所有的完全二叉树和满二叉树都可以补成一个完美二叉树.那么就当他们的叶子结点是存在的(地址为NULL),如果是完全二叉树,那么在层序遍历时只有最后才会遇到这些空节点,而算法的思路就是判断这些空节点的位置,如果不在末尾,那么便可以证明不是完全二叉树.
1 | bool isCompleteTree(Node* root) { |