PAT甲级 1123 Is It a Complete AVL Tree 完全平衡二叉树 (30分)

39 篇文章 0 订阅
3 篇文章 0 订阅

在这里插入图片描述
在这里插入图片描述

题意:

首先我们需要根据给出的序列建立一棵二叉平衡树,然后输出它的层序遍历,并且判断它是不是一个完全二叉树。
判断完全二叉树我们可以用dfs记录我们遍历到的结点的最大编号,若这棵树是完全二叉树,则这个编号一定等于n,凡是小于n或者大于n都可以证明不是一颗完全二叉树。

代码如下:

//平衡二叉树

#include<iostream>
#include<vector>
#include<math.h>
#include<queue>
using namespace std;

int max_index=-1;

struct node{//结点
    int key;
    node *left;
    node *right;
};

vector<int> vec;

node *rotate_left(node *root){//左旋
    node *t=root->right;
    root->right=t->left;
    t->left=root;
    return t;
}
node *rotate_right(node *root){//右旋
    node *t=root->left;
    root->left=t->right;
    t->right=root;
    return t;
}
node *rotate_left_right(node *root) {//先左后右旋
    root->left=rotate_left(root->left);
    return rotate_right(root);
}
node *rotate_right_left(node *root) {//先右后左旋
    root->right=rotate_right(root->right);
    return rotate_left(root);
}
int get_height(node *root) {//获得某个结点的高度
    if(root==NULL){
        return 0;
    }
    return max(get_height(root->left), get_height(root->right))+1;
}

node *insert_node(node *root,int key){//插入新结点
    if(root==NULL){//如果根结点为空
        root=new node();
        root->key=key;
        root->left=root->right=NULL;
    }else if(key<root->key){
        root->left=insert_node(root->left,key);
        if(get_height(root->left)-get_height(root->right)==2){
            if(key<root->left->key){//右旋
                root=rotate_right(root);
            }else{//先左后右旋
                root=rotate_left_right(root);
            }
        }
    }else{
        root->right=insert_node(root->right,key);
        if(get_height(root->left)-get_height(root->right)==-2){
            if(key>root->right->key){//左旋
                root=rotate_left(root);
            }else{//先右后左旋
                root=rotate_right_left(root);
            }
        }
    }
    return root;
}

void level_traversal(node *root){
    queue<node*> q;
    q.push(root);
    while(!q.empty()){
        node *temp=q.front();
        vec.push_back(temp->key);
        q.pop();
        if(temp->left!=NULL){
            q.push(temp->left);
        }
        if(temp->right!=NULL){
            q.push(temp->right);
        }
    }
}

void dfs(node *root,int index){
    if(index>max_index){
        max_index=index;
    }

    if(root->left==NULL&&root->right==NULL){
        return;
    }

    if(root->left!=NULL){
        dfs(root->left,2*index);
    }
    if(root->right!=NULL){
        dfs(root->right,2*index+1);
    }
}

int main() {
    int n,key;
    cin>>n;
    node *root=NULL;
    for(int i=0;i<n;i++) {
        cin>>key;
        root=insert_node(root,key);
    }
    dfs(root,1);
    level_traversal(root);
    for(int i=0;i<vec.size();i++){
        cout<<vec[i];
        if(i!=vec.size()-1){
            cout<<" ";
        }
    }
    cout<<endl;
    if(max_index==n){
        cout<<"YES"<<endl;
    }else{
        cout<<"NO"<<endl;
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值