团体程序设计天梯赛-练习集 L3-010 是否完全二叉搜索树 (30分)建树层序遍历 两种方法判断

L3-010 是否完全二叉搜索树 (30分)

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

输入格式:

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

输出格式:

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

输入样例1:

9
38 45 42 24 58 30 67 12 51

输出样例1:

38 45 24 58 42 30 12 67 51
YES

输入样例2:

8
38 24 12 45 58 67 42 51

输出样例2:

38 45 24 58 42 12 67 51
NO

判断是否完全二叉树有两种方法:

一是用数组存,下标乘2和下标乘2加1分别是他的两个子树,这样做的好处是简单,最后判断完全二叉树的时候只用判断前n个数都付上了值就ok了,但是有缺点就是如果给的节点数太大数组根本存不下,题目上是 n < = 20 n <= 20 n<=20,若 n < = 30 n <= 30 n<=30这种方法就写不了了,因为会有一种情况使下标达到 2 30 2^{30} 230,数组使存不下的,更何况n是一千一万的大小了。

第二种是用指针存,也就是真正的建树,这样的数据结构能存1e5的数据量。但是判断完全二叉树的时候就麻烦了一些。

放上以前写的代码以作对比,

//#include<bits/stdc++.h>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;
#define ri register int
#define ms(x, n) memset(x, n, sizeof(x))
#define wht() \
    int t;    \
    cin >> t; \
    while (t--)
#define For(i, a, b) for (ri i = a; i <= b; i++)
#define nowl now << 1
#define nowr now << 1 | 1
#define mi (l + r) / 2
#define ioss ios::sync_with_stdio(false)

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int maxn = 2e5 + 7;
const int maxm = 2e3 + 7;
const int mod = 1e9 + 7;

int dir[6][3] = {{0, 0, 1},  {0, 0, -1}, {0, 1, 0},
                 {0, -1, 0}, {1, 0, 0},  {-1, 0, 0}};
int n, v, m, l, d, s, t, o, e;
int ans = 0, tot = 0;
int a[maxn], b[maxn];
bool flag, vis[maxm];
char str[maxn];
string ss[maxn];

class node {
   public:
    int v;
    int len;
    int time;
    node(int v, int len, int time) : v(v), len(len), time(time) {}

    //	bool operator < (const node &b) const{
    //		return cost < b.cost;
    //	}
};
vector<node> ve[maxm];
vector<int> fa[maxm];

int mx = 1;
void build(int now, int x) {
    if (b[now] == 0) {
        b[now] = x;
        mx = max(now, mx);
        return;
    }
    if (x > b[now]) {
        build(nowl, x);
    } else {
        build(nowr, x);
    }
    return;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("D://hp//Desktop//Temporarily//test.txt", "r", stdin);
#endif

    ioss;

    int x, y, z;
    string s1, s2;
    cin >> n;
    if (n == 0) {
        cout << "YES";
        return 0;
    }
    For(i, 1, n) { cin >> a[i]; }
    b[1] = a[1];
    For(i, 2, n) { build(1, a[i]); }
    For(i, 1, mx) {
        if (!b[i]) continue;
        cout << b[i];
        if (i == mx) {
            cout << '\n';
        } else {
            cout << " ";
        }
    }
    if (mx == n) {
        cout << "YES";
    } else {
        cout << "NO";
    }
}

#include <bits/stdc++.h>
#include <limits.h>
#include <math.h>
#include <memory.h>
#include <stdio.h>

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define ms(x, n) memset(x, n, sizeof(x))
#define wht() \
    int _;    \
    for (scanf("%d", &_); _; _--)
#define For(i, a, b) for (int i = a; i <= (b); ++i)
#define Rof(i, a, b) for (int i = a; i >= (b); --i)
#define ioss ios::sync_with_stdio(false)
#define all(a) a.begin(), a.end()
#define ll long long
// #define input(x) scanf("%lld", &x);
// #define print(x) printf("%lld", x);
// #define println(x) printf("%lld\n", x);
typedef vector<int> vi;
typedef pair<int, int> pii;

const int maxn = 2e6 + 7;
const int maxm = 5e3 + 7;
const int MOD = 1e9 + 7;
const int mod = 998244353;

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline int input() {
    int x = 0, f = 0;
    char ch = 0;
    while (!isdigit(ch)) f |= ch == '-', ch = getchar();
    while (isdigit(ch)) x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();
    return f ? -x : x;
}

const int N = 1e5 + 5;
int n, m, k;
int a[N], b[N], f[N];
vi g[N];

struct node {
    int val;
    node *le, *ri;
};

void build(node *&r, int val) {
    if (!r) {
        r = new node, r->val = val, r->le = r->ri = nullptr;
        return;
    }
    if (val < r->val) build(r->ri, val);
    if (val > r->val) build(r->le, val);
}

void work() {
    n = input();
    if (n == 0) {
        puts("YES");
        return;
    }
    node *root = nullptr;
    For(i, 1, n) {
        int x = input();
        build(root, x);
    }
    queue<node *> q;
    q.push(root);
    int fir = 0;
    vi ve;
    int flag = 0;
    int leaf = 0;  //标记出现没右子树的节点
    while (q.size()) {
        int tot = q.size();
        For(i, 1, tot) {
            node *cur = q.front();
            q.pop();
            if (fir) putchar(' ');
            fir = 1;
            printf("%d", cur->val);
            // 如果该节点没左子树但有右子树,则不完全
            // 或者在出现过没有右子树的节点之后该节点有任意一子树都不完全
            if ((leaf && (cur->le || cur->ri)) || (!cur->le && cur->ri)) {
                flag = 1;
            }
            if (cur->le) q.push(cur->le);
            if (cur->ri)
                q.push(cur->ri);
            else
                leaf = 1;
        }
        ve.push_back(tot);
    }
    // for (auto i : ve) {
    //     cout << i << "\n";
    // }
    ll ans = 1;
    For(i, 0, (int)ve.size() - 2) {
        // cout << ve[i] << " " << ans << "\n";
        if (ve[i] != ans) {
            flag = 1;
            break;
        }
        ans <<= 1;
    }
    puts(flag ? "\nNO" : "\nYES");
}

signed main() {
#ifndef ONLINE_JUDGE
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif
    work();
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值