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

来源:互联网 发布:windows aero桌面性能 编辑:程序博客网 时间:2024/05/22 08:17

完全二叉树的定义(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;}
原创粉丝点击