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

来源:互联网 发布:js手机上下滑动事件 编辑:程序博客网 时间:2024/06/10 09:20

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

定义:

         完全二叉树就是除最后一层外,每一层上的节点数均达到最大值,在最后一层上只缺少右边的若干节点。

         满二叉树是特殊的完全二叉树。

如图:

这些均为完全二叉树:

            
            这个为满二叉树

这些均为不完全二叉树:


解题思路:

1.利用标志位求解

                                     

 

设置标记flag=false,从根节点开始层序遍历入队列,如果队列不为空,则一直循环,遇到第一个没有左孩子或者右孩子的节点,设置标志位为true,则继续向后遍历时遇到有左右孩子的节点时,说明该树不是完全二叉树。

bool IsCompleteBinartTree(){bool flag = false;     //设置标志位queue<Node*> qq;qq.push(_root);Node* cur = qq.front();while (cur){if (cur->_left == NULL && cur->_right != NULL){return false;}//当前节点有左右孩子,且之前标志位为true时说明不为完全二叉树if (flag == true && ((cur->_left) || (cur->_right))){return false;}//当前节点只要有一个孩子为空,就设置标志位为trueif (cur->_left == NULL || cur->_right == NULL){flag = true;}if (cur->_left){qq.push(cur->_left);    //要依次将队头元素的左右孩子压入队列}if (cur->_right){qq.push(cur->_right);}qq.pop();    //弹出队头if(!qq.empty()){cur = qq.front();}else{cur = NULL;}}return true;}
2.优化:辅助队列方法求解,标志位的方法相对要繁琐些

                                                  


代码:

bool IsCompleteBinaryTree(){queue<Node*> qq;qq.push(_root);Node* cur = qq.front();while (cur){qq.push(cur->_left);qq.push(cur->_right);qq.pop();cur = qq.front();     //新的队头}//出了循环,说明此时队头遇到NULL,如果队列全部为空,即是完全二叉树while (!qq.empty()){if (qq.front()){return false;}qq.pop();}return true;}

完整代码:

#include <iostream>#include <Windows.h>#include <assert.h>#include <queue>using namespace std;template <class T>struct BinaryTreeNode{T _data;     //节点数据BinaryTreeNode<T>* _left;BinaryTreeNode<T>* _right;BinaryTreeNode(const T& data):_data(data), _left(NULL), _right(NULL){}};template <class T>class BinaryTree{typedef BinaryTreeNode<T> Node;public:BinaryTree():_root(NULL){}~BinaryTree(){}BinaryTree(const T* a, size_t size, const T& invalid){size_t index = 0;    //下标_root = _CreatTree(a, size, index, invalid);}////设置标志位方法//bool IsCompleteBinaryTree()//{//bool flag = false;//queue<Node*> qq;//qq.push(_root);//Node* cur = qq.front();//while (cur)//{//if (cur->_left == NULL && cur->_right != NULL)//{//return false;//}////当前节点有左右孩子,且之前标志位为true时说明不为完全二叉树//if (flag == true && ((cur->_left) || (cur->_right)))//{//return false;//}////当前节点只要有一个孩子为空,就设置标志位为true//if (cur->_left == NULL || cur->_right == NULL)//{//flag = true;//}//if (cur->_left)//{//qq.push(cur->_left);    //要依次将队头元素的左右孩子压入队列//}//if (cur->_right)//{//qq.push(cur->_right);//}//qq.pop();    //弹出队头//if(!qq.empty())//{//cur = qq.front();//}//else//{//cur = NULL;//}//}//return true;//}//利用辅助队列求解bool IsCompleteBinaryTree(){queue<Node*> qq;qq.push(_root);Node* cur = qq.front();while (cur){qq.push(cur->_left);qq.push(cur->_right);qq.pop();cur = qq.front();     //新的队头}//出了循环,说明此时队头遇到NULL,如果队列全部为空,即是完全二叉树while (!qq.empty()){if (qq.front()){return false;}qq.pop();}return true;}protected:Node* _CreatTree(const T* a, size_t size, size_t& index, const T& invalid){assert(a);Node* root = NULL;if (index < size && a[index] != invalid){root = new Node(a[index]);root->_left = _CreatTree(a, size, ++index, invalid);root->_right = _CreatTree(a, size, ++index, invalid);}return root;}protected:Node* _root;    //根节点};

#include "IsCompleteBinaryTree.h"void TestIsCompleteBinaryTree(){int a[] = { 0, 1, 3, '#', '#', '#', 2 };size_t size = sizeof(a) / sizeof(a[0]);BinaryTree<int> www(a, size, '#');cout <<"是否为完全二叉树:"<< www.IsCompleteBinaryTree() << endl;}int main(){TestIsCompleteBinaryTree();system("pause");return 0;}


阅读全文
2 0
原创粉丝点击