Description:

将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果。

Input:

输入第一行给出一个不超过20的正整数N;第二行给出N个互不相同的正整数,其间以空格分隔。

Output:

将输入的N个正整数顺序插入一个初始为空的二叉搜索树。在第一行中输出结果树的层序遍历结果,数字间以1个空格分隔,行的首尾不得有多余空格。第二行输出“YES”,如果该树是完全二叉树;否则输出“NO”。

Sample Input:

9
38 45 42 24 58 30 67 12 51

Sample Output:

38 45 24 58 42 30 12 67 51
YES

Sample Input:

8
38 24 12 45 58 67 42 51

Sample Output:

38 45 24 58 42 12 67 51
NO

题目链接

利用数组按照题目要求建立二叉树,最后层序遍历输出时判断是否为完全二叉树。
数组建立二叉树通过下标定位:

  • 若根节点下标为0:设节点下标为n,此节点左孩子下标为2n+1,右孩子下标为2n+2
  • 若根节点下标为1:设节点下标为n,此节点左孩子下标为2n,右孩子下标为2n+1

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long ll;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5+5;
const double eps = 1e-5;
const double e = 2.718281828459;

int n, num;
// 二叉树数组
// 若根节点下标为0:设节点下标为n,此节点左孩子下标为2*n+1,右孩子下标为2*n+2
// 若根节点下标为1:设节点下标为n,此节点左孩子下标为2*n,右孩子下标为2*n+1
int tree[maxn];

// 根据题目要求递归建立二叉树
void Build_tree(int a) {
    // 若节点为空,则将数值放置在此
    if (tree[a] == -1) {
        tree[a] = num;
    }
    // 小于父节点在右侧寻找
    else if (num < tree[a]) {
        // 下标计算可以利用位运算
        Build_tree(a * 2 + 2);
    }
    // 大于在左侧寻找
    else {
        // 下标计算可以利用位运算
        Build_tree(a * 2 + 1);
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;
    mem(tree, -1);
    for (int i = 0; i < n; ++i) {
        cin >> num;
        // 从根节点开始寻找数值应该插入位置
        Build_tree(0);
    }
    bool flag = 1;
    int cnt = 1;
    for (int i = 0; cnt <= n; ++i) {
        // 层序遍历中若出现空节点则不是完全二叉树,改变判断bool变量值
        if (tree[i] == -1) {
            flag = 0;
        }
        // 按照要求输出层序遍历结果
        else {
            if (cnt == n) {
                cout << tree[i] << endl;
            }
            else {
                cout << tree[i] << " ";
            }
            cnt++;
        }
    }
    // 根据判断是否为完全二叉树的bool变量输出结果
    if (flag) {
        cout << "YES" << endl;
    }
    else {
        cout << "NO" << endl;
    }
    return 0;
}