完全二叉树定义:除最后一层外,其它各层的结点数都达到最大个数,并且最后一层所有的结点都连续集中在最左边,这就是完全二叉树。
定义形象化:
(1)除最后一层外,其它各层的结点数都达到最大个数
如果一个结点的孩子数小于2,那这个结点一定在最后两层中的某一层,否则一定不是完全二叉树。因为,除最后一层,其他各层构成满二叉树。那么如果一个结点孩子数小于2,那它的后续结点必须是叶子结点。
(2)最后一层所有的结点都连续集中在最左边
如果出现左孩子为空,右孩子不为空的情况,则一定不是完全二叉树。
一、二叉树结构表示:
struct TreeNode{
TreeNode(int value):left(NULL),right(NULL),val(value){ }
TreeNode *left;
TreeNode *right;
int val;
};
二、前序构造一棵二叉树
数据存在data.txt的文件中,用前序序列表示,-1代表一个空节点。
void PreoderBuildTree(TreeNode *&root)
{
typedef std::pair<TreeNode*,int> PTI;
int value = -1;
stack<PTI> s;
ifstream ifs("data.txt");
ifs >> value;
if(value != -1) root = new TreeNode(value);
if(root) s.push(PTI(root,false));
PTI *curnode = &s.top();
while(!s.empty()){
while(curnode = &s.top(), curnode->second == false) {
ifs >> value;
if(value == -1) break;
curnode->second = true;
(curnode->first)->left = new TreeNode(value);
s.push(PTI((curnode->first)->left,false));
}
curnode = &s.top();
s.pop();
ifs >> value;
if(value == -1) continue;
(curnode->first)->right = new TreeNode(value);
s.push(PTI((curnode->first)->right, false));
}
ifs.close();
}
三、主程序逻辑:
bool JudgeCompleteBinaryTree(TreeNode *node){
if(NULL == node) return true;
queue<TreeNode*> q;
q.push(node);
TreeNode *curnode = NULL;
bool flag = false; //flag标识第一次出现右孩子为空
while(!q.empty()){
curnode = q.front();
q.pop();
if(curnode->left == NULL && curnode->right != NULL) return false; //左孩子为空,右孩子不为空
if(flag){
if(curnode->left == NULL && curnode->right == NULL)
;
else //后续结点不是叶子结点
return false;
}else{
if(curnode->right == NULL) flag = true;//出现右孩子为空,后续的结点必须都是叶子结点
if(curnode->left != NULL) q.push(curnode->left);
if(curnode->right != NULL) q.push(curnode->right);
}
}
return true;
}
四、调用接口:
int main(void)
{
TreeNode *root = NULL;
//前序建树
PreoderBuildTree(root);
if(JudgeCompleteBinaryTree(root))
std::cout << "True" << std::endl;
else
std::cout << "False" << std::endl;
}