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

        建树很容易,直接跳过。

        那怎样才是一颗完全二叉树呢?首先定义上就是叶子节点只出现在最外层和次外层,且左边的节点一定是完全的。

        基于这个原则,我们知道有种情况一定不是完全二叉树:

        但右节点不为空,左节点为空,一定不是完全二叉树。

        然后一颗真正的完全二叉树,当遍历到右节点为空,此时只可能是最后遍历结束了,但是,倘若这时候遍历还没有结束,那只能是这棵树不是完全二叉树。

        完整代码:

#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; ++ i)
#define per(i, a, b) for(int i = a; i >= b; -- i)
#define int long long
using namespace std;
struct Node{
    int value;
    struct Node *lNode,*rNode;
};
int n;
bool f,leef;
Node * insert(Node *root,int x){
    if(root == NULL){
        root = new Node;
        root->value = x;
        root->lNode = root->rNode = NULL;
        return root;
    }else{
        if(root->value > x){
            root->rNode = insert(root->rNode,x);
        }else{
            root->lNode = insert(root->lNode,x);
        }
    }
    return root;
}

vector<int> ans;
void layershow(Node *t){
    queue<Node*> q; q.push(t);
    while(q.size()){
        Node *u = q.front(); q.pop();
        ans.push_back(u->value);
        Node *l = u->lNode,*r = u->rNode;
        if( (l == NULL && r != NULL) || (leef && (l != NULL || r != NULL))) f = true;
        if(l != NULL) q.push(u->lNode);
        if(r != NULL) q.push(u->rNode);
        else leef = true;
    }
}


signed main()
{
    cin >> n;
    Node *root = NULL;
    rep(i,1,n){
        int x; cin >> x;
        root = insert(root,x);
    }

    layershow(root);


    int l = ans.size();
    rep(i,0,l-2) cout << ans[i] <<" ";
    cout << ans[l-1] << endl;
    if(!f) cout << "YES";
    else cout << "NO";
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值