Is it a complete binary search tree?
The subject requirements are as follows:
7-1 Is it a complete binary search tree (30 points)
to insert a sequence of given numbers into an initially empty binary search tree (defined as the left subtree with a large key and a right subtree with a small key), you need Determine whether the final tree is a complete binary tree, and give the result of its level-order traversal.Input format:
The first line of input gives a positive integer N not exceeding 20; the second line gives N different positive integers, separated by spaces.Output format:
sequentially insert the input N positive integers into an initially empty binary search tree. In the first line, output the result of the hierarchical traversal of the result tree. The numbers are separated by 1 space, and there must be no extra spaces at the beginning and end of the line. The second line outputs YES if the tree is a complete binary tree; otherwise it outputs NO.Input Sample 1:
9
38 45 42 24 58 30 67 12 51
Output Sample 1:
38 45 24 58 42 30 12 67 51
YES
Input Sample 2:
8
38 24 12 45 58 67 42 51
Output Sample 2:
38 45 24 58 42 12 67 51
NO
The idea of judging whether a tree is a complete binary tree:
1. If the tree is empty, return an error directly.
2. If the tree is not empty: traverse the binary tree in level order.
3. If the left and right children of a node are not empty, put its left and right children into the queue;
4. If a node is encountered, the left child is empty and the right child is not empty, then the tree must not be a complete binary tree;
5. If a node is encountered, the left child is not empty, the right child is empty; or the left and right children are empty; then the nodes in the queue after the node are all leaf nodes; the tree is a complete binary tree, otherwise it is not complete binary tree;
To put it simply, the child nodes are required to go left to right. When a node with a degree less than 2 is encountered, the following must be all leaves.
Code implementation (code algorithm is not optimized enough):
#include<stdio.h>
#include<stdlib.h>
struct TNode {
int Data;
struct TNode *Left, *Right;
};
struct TNode *Insert(struct TNode *BST, int X) //搜索二叉树的插入
{
if(!BST) {
BST = (struct TNode *)malloc(sizeof(struct TNode));
BST->Data = X;
BST->Left = BST->Right = NULL;
}
else {
if(X > BST->Data) {
BST->Left = Insert(BST->Left, X);
}
else if(X < BST->Data) {
BST->Right = Insert(BST->Right, X);
}
}
return BST;
}
int LevelorderTraversal(struct TNode *BT) //层序遍历
{
int t = 0, k = 1, flag = 1;
/*t是队头指针,k为队尾指针,flag用于标记是否为完全二叉树,非0即真
*flag == 2为标记,如果flag==2之后的所有结点不全为叶子节点,为否*/
struct TNode *s[21]; //队列大小
s[t] = BT; //第一个二叉树根结点入队列
while(t != k) { //t于k相等说明,队列为空(此非循环队列)。
if(!t) {
printf("%d", s[t]->Data); //第一个打印不用空格
}
else {
printf(" %d", s[t]->Data); //除第一个以外,其他前面加空格,这样保证了结尾不会有空格
}
if(s[t]->Left && s[t]->Right) { //若左右结点都不为空
if(flag == 2) { // 如果此结点已被标记,而此节点不为叶子,则不为完全二叉树
flag = 0; //标记为否
}
//遍历继续
s[k++] = s[t]->Left; //左子树入队
if(t == k) {
break;
}
s[k++] = s[t]->Right; //右子树入队
if(t == k) {
break;
}
}
else if(s[t]->Left && (!s[t]->Right)){ //如果左子树不为空,右子树为空
if(flag == 2) { // 如果此结点已被标记,而此节点不为叶子,则不为完全二叉树
flag = 0; //标记为否
}
//遍历继续
s[k++] = s[t]->Left;//左子树入队
if(flag != 0) { //如果此树已经确定不为完全二叉树,则不必标记
flag = 2; //若此树未被标记,则在此处标记,后面的节点需都为叶子才是完全二叉树,否则不是
}
if(t == k) {
break;
}
}
else if(!s[t]->Left && s[t]->Right){ //左子树为空,而右子树不为空,则此树一定是非完全二叉树
flag = 0; //标记为否
s[k++] = s[t]->Right; //右子树入队
if(t == k) {
break;
}
}
else { //如果左右子树都为空
if(flag == 1) { //并且此树还认为正确的
flag = 2; //标记为不一定正确
}
}
t ++; //队头指针右移,用于出队
}
return flag; //返回flag的值
}
int main()
{
int i, n, X, H;
struct TNode *BST = NULL;
scanf("%d", &n);
for(i = 0; i < n; i ++) {
scanf("%d", &X);
BST = Insert(BST, X);
}
if(LevelorderTraversal(BST) != 0) { //flag的值非0即真
printf("\nYES\n");
}
else {
printf("\nNO\n");
}
return 0;
}