Is the PTA a complete binary search tree?

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;
}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326659026&siteId=291194637