PAT 1123. Is It a Complete AVL Tree (30)

PAT 1123. Is It a Complete AVL Tree (30)

题目PAT(A) 1123

给定一个包含N个数的序列,将他们依次插入平衡二叉搜索树中,按照层序遍历的方式输出二叉搜索树中每个节点的值,并判断此是否为完全二叉树。

采用链表方式完成二叉树的存储,在读入新的数并将其插入原始二叉树后,判断此二叉树的平衡是否被破坏,如果二叉树平衡被破坏,需要根据情况完成二叉树的旋转,此部分代码如下:

Tree Insert(Tree tree, int a)
{
    if(tree == NULL){
        tree = Initialize(a);
        return tree;
    }
    if(a<tree->val){
        tree->left = Insert(tree->left, a);
        if(FindHeight(tree->left)-FindHeight(tree->right) > 1){       //平衡被破坏
            if(a<tree->left->val){
                tree = SingleLeft(tree);
            }
            else{
                tree = LeftRight(tree);
            }
        }
    }
    else{
        tree->right = Insert(tree->right, a);
        if(FindHeight(tree->right) - FindHeight(tree->left) > 1){
            if(a>tree->right->val)
                tree = SingleRight(tree);
            else
                tree = RightLeft(tree);
        }
    }
    return tree;
}

完成平衡二叉树的构建后,需要对其进行层序遍历,同时判断其是否为完全二叉树。
注意到如果使用数组存储完全二叉树,根节点存储在下标为1的位置,则完全二叉树的父节点与左右儿子节点的存储下标满足 parentIndex = index, leftChildIndex = index*2,
rightChildIndex = index*2+1。因此判断其是否为完全二叉树,我们只需要判断其孩子节点的下标是否越过n 的界限。
采用队列数据结构,树的根节点入队,而后判断队列是否为空,若队列非空,则弹出队首元素,并找到若为完全二叉树,队首元素在数组中的下标。 同时将弹出元素的左右儿子压入队列中,并按照父节点与子节点间下标的关系,进行标记。 判断是否出界,若出界,则不为完全二叉树。

代码如下:

#include<iostream>
#include<queue>
#include<vector>
using namespace std;
struct BinaryTree;
typedef struct BinaryTree *Tree;
struct BinaryTree
{
    int val;
    Tree left;
    Tree right;
};
Tree Initialize(int a)
{
    Tree tree = (Tree)malloc(sizeof(struct BinaryTree));
    tree->left = NULL;
    tree->right = NULL;
    tree->val = a;

    return tree;
}
int Max(int a, int b)
{
    if(a>b)
        return a;
    else
        return b;
}
int FindHeight(Tree tree)
{
    int height = 0;
    if(tree == NULL)
        return 0;
    if(tree->left == NULL && tree->right == NULL){
        height = 1;
        return height;
    }
    else{
        height = Max(FindHeight(tree->left), FindHeight(tree->right)) + 1;
        return height;
    }
}
Tree SingleLeft(Tree tree)
{
    Tree a = tree;
    Tree b = a->left;
    a->left = b->right;
    b->right = a;
    return b;
}
Tree SingleRight(Tree tree)
{
    Tree a = tree;
    Tree b = a->right;
    a->right = b->left;
    b->left = a;
    return b;
}
Tree LeftRight(Tree tree)
{
    Tree a = tree;
    Tree b = a->left;
    Tree c = b->right;
    b->right = c->left;
    a->left = c->right;
    c->left = b;
    c->right = a;
    return c;
}
Tree RightLeft(Tree tree)
{
    Tree a = tree;
    Tree b = tree->right;
    Tree c = b->left;
    b->left = c->right;
    a->right = c->left;
    c->left = a;
    c->right = b;
    return c;
}
Tree Insert(Tree tree, int a)
{
    if(tree == NULL){
        tree = Initialize(a);
        return tree;
    }
    if(a<tree->val){
        tree->left = Insert(tree->left, a);
        if(FindHeight(tree->left)-FindHeight(tree->right) > 1){
            if(a<tree->left->val){
                tree = SingleLeft(tree);
            }
            else{
                tree = LeftRight(tree);
            }
        }
    }
    else{
        tree->right = Insert(tree->right, a);
        if(FindHeight(tree->right) - FindHeight(tree->left) > 1){
            if(a>tree->right->val)
                tree = SingleRight(tree);
            else
                tree = RightLeft(tree);
        }
    }
    return tree;
}
Tree position;
void FindPosition(Tree tree, int a)
{
    Tree result;
    if(tree->val == a){
        position = tree;
        return;
    }

    else if(a<tree->val)
        FindPosition(tree->left, a);
    else
        FindPosition(tree->right, a);
    return;
}
int  FindIndex(int* flag, int a, int n)
{
    for(int i=1;i<=n;i++){
        if(a == flag[i]){
            return i;
        }
    }   
}
int main()
{
    int n;
    cin>>n;

    Tree tree = NULL;
    int num;

    for(int i=0;i<n;i++){
        cin>>num;
        tree = Insert(tree, num);
    }

    queue<int> Queue;
    int a;

    int* flag = (int*)malloc(sizeof(int)*(n+1));
    int tag = 1;

    Queue.push(tree->val);
    int index = 1;
    flag[index] = tree->val;
    while(!Queue.empty()){
        a = Queue.front();
        index = FindIndex(flag, a, n);
        Queue.pop();
        position = NULL;
        cout<<a;
        FindPosition(tree, a);
        if(!Queue.empty() || (Queue.empty() && (position->left != NULL || position->right != NULL)))
            cout<<" ";
        if(position->left != NULL){
            Queue.push(position->left->val);
            if(index*2 <=n){
                flag[index*2] = position->left->val;
            }
            else{
                tag = 0;
            }
        }
        if(position->right != NULL){
            Queue.push(position->right->val);
            if(index*2 +1<=n){
                flag[index*2+1] = position->right->val;
            }
            else
                tag = 0;
        }
    }
    cout<<endl;
    if(tag==1)
        cout<<"YES";
    else
        cout<<"NO";
    system("pause");
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值