平衡二叉树

#include <bits/stdc++.h>
#define ElemType int

using namespace std;

typedef struct AVLTree
{
    ElemType data;
    ElemType bal; /// 记录平衡因子
    struct AVLTree *Left;
    struct AVLTree *Right;
}Node;

int GetBal(Node *p); /// 求节点平衡因子
Node *LL(Node *p); /// 右旋
Node *RR(Node *p); /// 左旋
Node *LR(Node *p); /// 先右旋再左旋
Node *RL(Node *p); /// 先左旋再右旋
Node *AVLCreat(Node *root, ElemType x);
void InTraversal(Node *root);

int main()
{
    int n;
    while(cin >> n)
    {
        Node *root = NULL; /// 初始化很重要!
        for(int i = 0; i < n; i++)
        {
            int x;
            cin >> x;
            root = AVLCreat(root, x);
        }
        cout << root->data << endl;
        //InTraversal(root);
    }
    return 0;
}

int GetBal(Node *p)
{
    if(!p)
    {
        return -1;
    }
    else
    {
        return p->bal;
    }
}

Node *LL(Node *root) /// 对于LL型 直接在不平衡的节点右旋
{
    Node *p; /// 画图便于理解
    p = root->Left;
    root->Left = p->Right;
    p->Right = root;
    p->bal = max(GetBal(p->Left), GetBal(p->Right)) + 1; /// get平衡因子
    root->bal = max(GetBal(root->Left), GetBal(root->Right)) + 1; /// 因为此时节点位置改变 所以重新计算此时节点的平衡因子
    return p; /// 此时p为新的子树根节点
}

Node *RR(Node *root) /// 同上QvQ
{
    Node *p;
    p = root->Right;
    root->Right = p->Left;
    p->Left = root;
    p->bal = max(GetBal(p->Left), GetBal(p->Right)) + 1; /// get平衡因子
    root->bal = max(GetBal(root->Left), GetBal(root->Right)) + 1; /// 因为此时节点位置改变 所以重新计算此时节点的平衡因子
    return p; /// 此时p为新的子树根节点
}

Node *LR(Node *p) /// 对于LR型 先对失衡节点的左子树进行左旋 再对整个子树右旋
{
    p->Left = RR(p->Left); /// 为什么感觉自己不分左右了2333
    return LL(p); /// 我真的不分左右了!!!!!!
}
/// 理解没错 博客有毒

Node *RL(Node *p) /// 对于RL型 先对失衡节点的右子树进行右旋 再对整个子树左旋
{
    p->Right = LL(p->Right);
    return RR(p);
}

Node *AVLCreat(Node *root, ElemType x)
{
    if(!root)
    {
        root = new Node;
        root->data = x;
        root->bal = -1;
        root->Left = NULL;
        root->Right = NULL;
    }
    else
    {
        if(x < root->data)
        {
            root->Left = AVLCreat(root->Left, x);

            if(GetBal(root->Left) - GetBal(root->Right) > 1) /// 进入左子树后 只会出现LL或是LR型
            {
                if(root->Left->data > x) ///则进入左节点的左子树 为LL型
                {
                    root = LL(root);
                }
                else
                {
                    root = LR(root);
                }
            }
        }
        else
        {
            root->Right = AVLCreat(root->Right, x);

            if(GetBal(root->Right) - GetBal(root->Left) > 1)
            {
                if(root->Right->data < x)
                {
                    root = RR(root);
                }
                else
                {
                    root = RL(root);
                }
            }
        }
    }
    root->bal = max(GetBal(root->Left), GetBal(root->Right)) + 1;
    return root;
}

void InTraversal(Node *root)
{
    if(root)
    {
        InTraversal(root->Left);
        cout << root->data << " ";
        InTraversal(root->Right);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值