判断一棵树是否为完全二叉树

完全二叉树的定义(Complete Binary Tree)

若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。

一棵二叉树至多只有最下面的两层上的结点的度数可以小于2,并且最下层上的结点都集中在该层最左边的若干位置上,则此二叉树成为完全二叉树。

**简单来说,完全二叉树(深度为K)即为K-1层为满二叉树(左右子树都存在),最后一层(第K层)的结点都是从左到右依次排列,中间不能有空结点。
**这里写图片描述
这里写图片描述
以三层为例,如图所示,图一图二为完全二叉树,图三图四不是完全二叉树。

判断完全二叉树的方法
判断完全二叉树类似与层序遍历,假设有如图所示的一颗二叉树。
这里写图片描述

首先将根结点放入队列中,如果不为空,那么再依次放入其左孩子和右孩子(空结点也入队列,此时的空结点也是队列中的数据),并且把对头的结点pop出去,递归直到遇到空结点为止。过程如表所示。
①当对头为空时,如果此时的队列除了空结点还有其它结点时,那么该二叉树一定不是完全二叉树。
②当对头为空时,如果此时的队列只有空结点,那么该二叉树一定为完全二叉树。
这里写图片描述

//判断二叉树是否为完全二叉树
    bool _IsCompleteBinaryTree(Node* root)
    {
        //如果该二叉树为空树,那么为完全二叉树。
        if (root == NULL)
            return true;
        //如果该二叉树只有一个结点,那么为完全二叉树。
        if (root->_Left == NULL && root->_Right == NULL)
            return true;

        queue<Node*> q; //创建一个队列。
        Node* ptr;

        q.push(root);   //先把根结点push到队列中。

        //当对列头不为空时,递归push其左孩子和右孩子。并且把对头pop出队列。
        while ((ptr = q.front()) != NULL)
        {
            q.pop();
            q.push(ptr->_Left);
            q.push(ptr->_Right);
        }

        while (q.empty() == false)
        {
            //依次出队列
            ptr = q.front();
            q.pop();

            //把每次出队列的ptr和Null做判断,如果不相等,那么就不是完全二叉树。
            if (ptr != NULL)
            {
                return false;
            }
        }

        return true;
    }

完整代码:

#include <iostream>
#include <queue>

using namespace std;

template<class T>
struct BinaryTreeNode
{
    BinaryTreeNode(const T data)
        :_data(data)
        ,_Left(NULL)
        ,_Right(NULL)
    {}

    T _data;
    BinaryTreeNode<T>* _Left;
    BinaryTreeNode<T>* _Right;
};

template<class T>
class BinaryTree
{
    typedef BinaryTreeNode<T> Node;

public:
    BinaryTree()
        :_root(NULL)
    {}

    BinaryTree(const T array[], size_t size, const T& invalid)
    {
        size_t index = 0;
        _CreateTree(_root, array, size, invalid, index);
    }

    bool IsCompleteBinaryTree()
    {
        return _IsCompleteBinaryTree(_root);
    }

private:
    //创建二叉树
    void _CreateTree(Node*& root, const T array[], size_t size, const T& invalid, size_t& index)
    {
        if (index < size && array[index] != invalid)
        {
            root = new Node(array[index]);
            _CreateTree(root->_Left, array, size, invalid, ++index);
            _CreateTree(root->_Right, array, size, invalid, ++index);
        }
    }

    //判断二叉树是否为完全二叉树
    bool _IsCompleteBinaryTree(Node* root)
    {
        //如果该二叉树为空树,那么为完全二叉树。
        if (root == NULL)
            return true;
        //如果该二叉树只有一个结点,那么为完全二叉树。
        if (root->_Left == NULL && root->_Right == NULL)
            return true;

        queue<Node*> q; //创建一个队列。
        Node* ptr;

        q.push(root);   //先把根结点push到队列中。

        //当对列头不为空时,递归push其左孩子和右孩子。并且把对头pop出队列。
        while ((ptr = q.front()) != NULL)
        {
            q.pop();
            q.push(ptr->_Left);
            q.push(ptr->_Right);
        }

        while (q.empty() == false)
        {
            ptr = q.front();
            q.pop();

             //把每次出队列的ptr和Null做判断,如果不相等,那么就不是完全二叉树。
            if (ptr != NULL)
            {
                return false;
            }
        }

        return true;
    }

private:
    BinaryTreeNode<T>* _root;
};

int main()
{
    char* ptr = "124###35##6";
    BinaryTree<char> t(ptr, strlen(ptr), '#');

    cout<<t.IsCompleteBinaryTree()<<endl;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值