// 判断一棵树是否为完全二叉树 #include#include #include using namespace std; const int N = 20; // 定义树的节点的结构体 struct BTNode { char data; // 数据域 BTNode* left; // 左孩子指针 BTNode* right; // 右孩子指针 }; class BTree { public: // 构造函数 BTree() { this->root = NULL; // 初始化根节点为空 } // 利用前序遍历建立二叉树 void CreateTree(BTNode** root) { char x; cin >> x; if (x == '#') *root = NULL; else { *root = new BTNode[N]; assert(*root); // 断言 (*root)->data = x; // 给该根节点赋值 CreateTree(&(*root)->left); // 递归建立左子树 CreateTree(&(*root)->right); // 递归建立右子树 } } // 判断是否为完全二叉树 bool IsCompleteBTree() { if (this->root == NULL) return false; // 若根节点为空,则不是完全二叉树 bool isonlyLeft = false; // 标记仅有左孩子无有孩子的节点 queue q; // 创建一个队列存储通过层序遍历出的节点 q.push(root); while (!q.empty()) // 若队列非空,则进入循环 { BTNode* cur = q.front(); // 用cur来记录下队头 q.pop(); // 记录下队头后将队头出队 if (isOnlyLeft) // 如果标记到了仅有左孩子的节点,则进入这个判断 { // 若这是完全二叉树,则标记之后进行判断的节点都应为叶子节点,若有不是叶子节点,则返回false if (cur->left || cur->right) return false; } else { if (cur->left == NULL && cur->right != NULL) // 存在右孩子而无左孩子,一定不是完全二叉树 return false; else if (cur->left != NULL && cur->right == NULL) // 仅存在左孩子,有可能是完全二叉树 { q.push(cur->left); // 将左孩子入队 isonlyLeft = true; // 找到仅有左孩子的节点并将其标记 } else if (cur->left != NULL && cur->right != NULL) // 左右孩子都存在,都入队后继续循环判断 { q.push(cur->left); q.push(cur->right); } else if (cur->left == NULL && cur->right == NULL) // 左右孩子都不存在,若这是完全二叉树,则这应该是叶子节点,将其标记继续循环判断 isonlyLeft = true; } } return true; } BTNode* root; }; int main() { BTree t; // 创建一个二叉树对象 t.CreateTree(&t.root); // 利用前序遍历建立一棵二叉树 if (t.IsCompleteBTree()) cout << "YES" << endl; else cout << "NO" << endl; return 0; }



