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

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

程序员文章站 2022-06-05 20:15:00
...

完全二叉树的定义(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;
}
相关标签: 完全二叉树