[DSAA-Lab7]A. Complete binary tree

数据结构与算法分析A Lab 7 A题题解

Description

Alice has a binary tree of n nodes. These nodes are numbered from 1 to n, she does not know if this tree is a complete binary tree or not. She turns to you for help. We guarantee that the input is a binary tree.

Input

The first line will be an integer T, which is the number of the test cases(1 <= T <= 14). For each test case, the first line will be an integer n (1<=n<=150000). Then followed by n lines, each line will be two integers x and y, the i-th line means the left child of node i is x, the right child of node i is y. If node i has no left child, then x will be 0, if node i has no right child, then y will be 0.

Output

For each test output Yes or No in one line.

Sample Input

1
5
2 3 
4 0
5 0
0 0
0 0

Sample Output

No

思路

题意是给出一棵树,问其是否是完全二叉树。

注意点1不一定是根。

Solution

队列

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N = 150010;
struct node
{
    int l, r;
} tr[N];
int fa[N];
queue<int> q;
bool solve()
{
    int n;
    scanf("%d", &n);
    memset(fa, 0, sizeof fa);
    for (int i = 1; i <= n; ++i)
    {

        scanf("%d%d", &tr[i].l, &tr[i].r);
        fa[tr[i].l] = i;
        fa[tr[i].r] = i;
    }
    int root = 1;
    while (fa[root])
        root = fa[root];

    while (!q.empty())
        q.pop();
    q.push(root);

    bool flag = false;
    while (!q.empty())
    {
        int x = q.front(); 
        if (x == 0)
            flag = true;
        else
        {
            if (flag)
                return false;
            q.push(tr[x].l);
            q.push(tr[x].r);
        }
        q.pop();
    }
    return true;
}
int main()
{
    int T; scanf("%d", &T);
    while (T--)
        puts(solve() ? "Yes" : "No");
    return 0;
}

递归

来自郝老师

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn = 150005;
int n, f, s, son[maxn][2], sum[maxn], vis[maxn];
bool complete, flag;
int dfs_mx(int p, int deep)
{
    if (p == 0)
        return 0;
    sum[deep]++;
    return max(max(dfs_mx(son[p][0], deep + 1), dfs_mx(son[p][1], deep + 1)), deep);
}
void dfs(int p, int deep, int mxd)
{
    if (deep >= mxd)
        return;
    if (deep == mxd - 1)
        if (complete)
        {
            if (son[p][0])
                if (son[p][1])
                    return;
                else
                    complete = false;
            else
                if (son[p][1])
                    flag = false;
                else
                    complete = false;
        }
        else
            if (son[p][0] + son[p][1])
                flag = false;
    if (flag == false)
        return;
    dfs(son[p][0], deep + 1, mxd);
    dfs(son[p][1], deep + 1, mxd);
}
int main(void)
{
    int T;
    scanf("%d", &T);
    while (T--)
    {
        flag = true;
        complete = true;
        scanf("%d", &n);
        memset(sum, 0, sizeof sum);
        memset(vis, 0, sizeof vis);
    
        for (int i = 1; i <= n; i++)
        {
            son[i][0] = son[i][1] = 0;
        }
        for (int i = 1; i <= n; i++)
        {
            scanf("%d%d", &son[i][0], &son[i][1]);
            vis[son[i][0]] = 1;
            vis[son[i][1]] = 1;
        }
        bool istree = false;
        for (int i = 1; i <= n; i++)
            if (vis[i] == 0)
            {
                if (istree)
                    flag = false;
                istree = true;
                int mxd = dfs_mx(i, 0);
                for (int j = 0; j < mxd; j++)
                    if (sum[j] != (1 << j))
                    {
                        flag = false;
                        break;
                    }
                if (flag)
                    dfs(i, 0, mxd);
            }
        if (flag)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

正解

利用二叉树标号的规律

#include <cstdio>
#include <cstring>
using namespace std;
const int N = 150010;
struct node
{
    int l, r;
} tr[N];
int n, fa[N];
bool flag = true;
void dfs(int now, int k)
{
    if (now == 0)
        return;
    if (flag == false)
        return;
    if (k > n)
        flag = false;
    dfs(tr[now].l, k << 1);
    dfs(tr[now].r, k << 1 | 1);
}
void solve()
{
    scanf("%d", &n);
    memset(fa, 0, sizeof fa);
    for (int i = 1; i <= n; ++i)
    {
        scanf("%d%d", &tr[i].l, &tr[i].r);
        fa[tr[i].l] = i;
        fa[tr[i].r] = i;
    }
    int root = 1;
    while (fa[root])
        root = fa[root];
    flag = true;
    dfs(root, 1);
    puts(flag ? "Yes" : "No");
}
int main()
{
    int T; scanf("%d", &T);
    while (T--)
        solve();
    return 0;
}
评论区

Gitalking ...

Markdown is supported

Be the first guy leaving a comment!