SDUT 3374 数据结构实验之查找二:平衡二叉树

Problem Description

根据给定的输入序列建立一棵平衡二叉树,求出建立的平衡二叉树的树根。
Input

输入一组测试数据。数据的第1行给出一个正整数N(n <= 20),N表示输入序列的元素个数;第2行给出N个正整数,按数据给定顺序建立平衡二叉树。
Output

输出平衡二叉树的树根。
Example Input

5
88 70 61 96 120
Example Output

70
先贴上学AVL树时参考的课本代码, 待会把自己改装过的代码贴上

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#define LH 1
#define RH -1
#define EH 0
using namespace std;
typedef int Elemtype;
typedef struct node
{
    Elemtype data;
    struct node *left;
    struct node *right;
    int bf;
} BSTNode, *BSTree;

void R_Rotate(BSTree &p)
{
    BSTree lc;
    lc = p -> left;
    p -> left = lc -> right;
    lc -> right = p;
    p = lc;
}
void L_Rotate(BSTree &p)
{
    BSTree rc = p -> right;
    p -> right = rc -> left;
    rc -> left = p;
    p = rc;
}
void LeftBalance(BSTree& root)
{
    BSTree lc = root -> left;
    BSTree rd;
    switch(lc -> bf)
    {
    case LH:
        lc -> bf = root -> bf = EH;
        R_Rotate(root);
        break;
    case RH:
        rd = lc -> right;
        switch(rd -> bf)
        {
        case LH:
            root -> bf = RH;
            lc -> bf = EH;
            break;
        case EH:
            root -> bf = lc -> bf = EH;
            break;
        case RH:
            root -> bf = EH;
            lc -> bf = LH;
            break;
        }
    rd -> bf = EH;
    L_Rotate(root -> left);
    R_Rotate(root);
    }
}
void RightBalance(BSTree &root)
{
    BSTree rc = root -> right;
    BSTree ld;
    switch(rc -> bf)
    {
    case RH:
        L_Rotate(root);
        rc -> bf = root -> bf = EH;
        break;
    case LH:
    {
        ld = rc -> left;
        switch(ld -> bf)
        {
        case LH:
            root -> bf = EH;
            rc -> bf = RH;
            break;
        case EH:
            root -> bf = rc -> bf = EH;
        case RH:
            root -> bf = LH;
            rc -> bf = EH;
        }
    }
    ld -> bf = EH;
    R_Rotate(root -> right);
    L_Rotate(root);
    }
}
bool InsertAVL(BSTree &root, Elemtype e, bool &taller)
{
    if(!root)
    {
        root = (BSTree)malloc(sizeof(BSTNode));
        root -> left = root -> right = NULL;
        root -> bf = EH;
        root -> data = e;
        taller = true;
    }
    else
    {
        if(e == root -> data)
        {
            taller = false;
            return 0;
        }
        if(e < root -> data)
        {

            if(!InsertAVL(root -> left, e, taller))
            {
                return 0;
            }
            if(taller)
            {
                switch(root -> bf)
                {
                case LH:
                    LeftBalance(root);
                    taller = false;
                    break;
                case EH:
                    root -> bf = LH;
                    taller = true;
                    break;
                case RH:
                    root -> bf = EH;
                    taller = false;
                    break;

                }
            }
        }
        else
        {
            if(!InsertAVL(root -> right, e, taller))
            {
                return 0;
            }
            if(taller)
            {
                switch(root -> bf)
                {
                case LH:
                    root -> bf = EH;
                    taller = false;
                    break;
                case EH:
                    root -> bf = RH;
                    taller = true;
                    break;
                case RH:
                    RightBalance(root);
                    taller = false;
                    break;
                }
            }

        }
    }
    return true;
}

int main()
{
    BSTree root = NULL;
    int n;
    while(cin >> n)
    {
        root = NULL;
        Elemtype t;

        for(int i = 0; i < n; i++)
        {
            bool flag = false;
            scanf("%d", &t);
            InsertAVL(root, t, flag);
        }
        printf("%d\n", root -> data);
    }
    return 0;
}

下面是我自己写的,去掉了一些关于平衡因子的操作,用树的深度来判断用哪个旋转。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#define LH 1
#define RH -1
#define EH 0
using namespace std;
typedef int Elemtype;
typedef struct node
{
    Elemtype data;
    struct node *left;
    struct node *right;
    int deep;//树的深度
} BSTNode, *BSTree;
int Deep(BSTree &root)//返回树的深度
{
    if(!root)
        return -1;
    return root -> deep;
}
void R_Rotate(BSTree &p)//右单旋操作
{
    BSTree lc = p -> left;
    p -> left = lc -> right;
    lc -> right = p;
    lc -> deep = max(Deep(lc -> left), Deep(lc -> right)) + 1;
    p -> deep = max(Deep(p -> left), Deep(p -> right)) + 1;
    p = lc;
}
void L_Rotate(BSTree &p)//左单旋操作
{
    BSTree rc = p -> right;
    p -> right = rc -> left;
    rc -> left = p;
    p -> deep = max(Deep(p -> left), Deep(p -> right)) + 1;
    rc -> deep = max(Deep(rc -> right), Deep(rc -> left)) + 1;
    p = rc;
}
bool Insert(BSTree &root, Elemtype e)//插入节点e
{
    if(!root)
    {
        root = new BSTNode;
        root -> data = e;
        root -> left = root -> right = NULL;
        root -> deep = 0;
        return true;
    }
    if(e == root -> data)
    {
        return false;//无需插入,返回false,可忽略此处操作
    }
    else if(e < root -> data)//插入左子树
    {
        Insert(root -> left, e);
        if(Deep(root -> left) - Deep(root -> right) == 2)//不平衡
        {
            if(e < root -> left -> data)//判断右单旋条件
            {
                R_Rotate(root);
            }
            else//左右双旋
            {
                L_Rotate(root -> left);
                R_Rotate(root);
            }
        }
    }
    else//插入右子树
    {
        Insert(root -> right, e);
        if(Deep(root -> right) - Deep(root -> left) == 2)//判断不平衡
        {
            if(e < root -> right -> data)//判断右左双旋条件
            {
                R_Rotate(root -> right);
                L_Rotate(root);
            }
            else//判断左单旋
            {
                L_Rotate(root);
            }
        }
    }
    root -> deep = max(Deep(root -> left), Deep(root -> right)) + 1;//更新深度值
    return true;
}
int main()
{
    int n;
    while(cin >> n)
    {
        BSTree root = NULL;
        for(int i = 0; i < n; i++)
        {
            int t;
            scanf("%d", &t);
            Insert(root, t);
        }
        printf("%d\n", root -> data);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值