《数据结构》课程设计——平衡二叉树

数据结构课程设计,含分裂和合并

运行环境:VS2017

#include<stdio.h>
#include<malloc.h>

#define OVERFLOW -1
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define LH 1  //左高
#define EH 0   //等高
#define RH -1  //右高

typedef int RcdType;
typedef int Status;

//存放输入数据的链表结构体
typedef struct ListNode {
    RcdType data;
    ListNode *next;
}ListNode, *List;

//平衡二叉树结构体
typedef struct BBSTNode {
    RcdType data;
    int bf;
    BBSTNode *lchild, *rchild;
}BBSTNode, *BBSTree;

//栈结点结构体
typedef struct LSNode {
    BBSTree data;
    struct LSNode *next;
}LSNode, *LStack;

//链队列结构体
typedef struct LQNode {
    BBSTree elem;
    struct LQNode *next;
}LQNode, *QueuePtr;

//队列结点结构体
typedef struct {
    QueuePtr front;
    QueuePtr rear;
}LQueue;

//初始化一个链栈
Status InitStack_LS(LStack &S) {
    S = NULL;
    return OK;
}

//进栈
Status Push_LS(LStack &S, BBSTree e) {
    LSNode *t;
    t = (LSNode*)malloc(sizeof(LSNode));
    if (NULL == t) return OVERFLOW;
    t->data = e;
    t->next = S;
    S = t;
    return OK;
}

//出栈
Status Pop_LS(LStack &S, BBSTree &e) {
    LSNode *t;
    if (S == NULL) return ERROR;
    t = S;
    e = t->data;
    S = S->next;
    return OK;
}


//获得栈顶元素
Status GetTop_LS(LStack S, BBSTree &e) {
    if (NULL == S) return ERROR;
    else {
        e = S->data;
        return OK;
    }
}

//判断栈是否为空
Status StackEmpty_LS(LStack S) {
    if (NULL == S) return TRUE;
    else return FALSE;
}

//初始化链队列
void InitQueue_LQ(LQueue &Q) {
    Q.front = NULL;
    Q.rear = NULL;
}

//进队
Status EnQueue_LQ(LQueue &Q, BBSTree e) {
    LQNode *p;
    p = (LQNode*)malloc(sizeof(LQNode));
    if (NULL == p)
        return OVERFLOW;
    p->elem = e;
    p->next = NULL;
    if (NULL == Q.front) Q.front = p;  //e插入空队列
    else Q.rear->next = p;  //e插入非空队列
    Q.rear = p;  //队尾指针指向新的队尾
    return OK;
}

//出队
Status DeQueue_LQ(LQueue &Q, BBSTree &e) {
    LQNode *p;
    if (NULL == Q.front)
        return ERROR;
    p = Q.front;
    e = p->elem;
    Q.front = p->next;
    if (Q.rear == p) Q.rear = NULL;
    free(p);
    return OK;
}


//左旋调整
void L_Rotate(BBSTree &p) {
    BBSTree rc = p->rchild;
    p->rchild = rc->lchild;
    rc->lchild = p;
    p = rc;
}

//右旋调整
void R_Rotate(BBSTree &p) {
    BBSTree lc = p->lchild;
    p->lchild = lc->rchild;
    lc->rchild = p;
    p = lc;
}

//左平衡处理操作
void LeftBalance(BBSTree &T) {
    BBSTree lc, rd;
    lc = T->lchild;
    switch (lc->bf) {

    case LH: T->bf = lc->bf = EH; R_Rotate(T);break;//LL
    case RH://LR
        rd = lc->rchild;
        switch (rd->bf) {
        case LH:T->bf = RH; lc->bf = EH; break;
        case EH:T->bf = lc->bf = EH; break;
        case RH:T->bf = EH; lc->bf = LH; break;
        }
        rd->bf = EH;
        L_Rotate(T->lchild);
        R_Rotate(T);
        break;
    case EH:
        T->bf = LH;
        lc->bf = RH;
        R_Rotate(T);
    }
}

//右平衡处理操作
void RightBalance(BBSTree &T)
{
    BBSTree rd, lc;
    rd = T->rchild;
    switch (rd->bf) {

    case RH: T->bf = rd->bf = EH;//RR
        L_Rotate(T);
        break;
    case LH:  lc = rd->lchild;//RL
        switch (lc->bf) {
        case LH: T->bf = EH; rd->bf = RH; break;
        case RH: T->bf = LH; rd->bf = EH; break;
        case EH: T->bf = rd->bf = EH;    break;
        }
        lc->bf = EH;
        R_Rotate(T->rchild);
        L_Rotate(T);
        break;

    case EH:
        T->bf = RH;
        rd->bf = LH;
        L_Rotate(T);
        break;
    }
}

//平衡二叉树的深度
int BBSTreeDepth(BBSTree T) {
    int ldepth, rdepth;
    if (NULL == T)
        return 0;
    else {
        ldepth = BBSTreeDepth(T->lchild);
        rdepth = BBSTreeDepth(T->rchild);
        return 1 + (ldepth > rdepth ? ldepth : rdepth);
    }
}
//平衡二叉树的查找
Status SearchAVL(BBSTree T, RcdType x)
{
    if (T == NULL)
        return FALSE;
    if (x == T->data)
        return TRUE;
    else if (x > T->data)
        return SearchAVL(T->rchild, x);
    else
        return SearchAVL(T->lchild, x);
}
//平衡二叉树的插入操作
Status InsertAVL(BBSTree &T, RcdType e, Status &taller) {
    if (NULL == T) {//T为空,树长高
        T = (BBSTree)malloc(sizeof(BBSTNode));
        T->data = e;
        T->bf = EH;
        T->lchild = NULL;
        T->rchild = NULL;
        taller = TRUE;
    }
    else if (e == T->data) {//已存在结点,插入失败
        taller = FALSE;
        return FALSE;
    }
    else if (e < T->data) {
        if (FALSE == InsertAVL(T->lchild, e, taller))
            return FALSE;
        if (TRUE == taller) {
            switch (T->bf) {
            case LH: LeftBalance(T); taller = FALSE; break;//原左高,左平衡处理
            case EH: T->bf = LH; taller = TRUE; break;//原等高,右变高
            case RH: T->bf = EH; taller = FALSE; break;//原右高,变等高
            }
        }
    }
    else {
        if (FALSE == InsertAVL(T->rchild, e, taller))
            return FALSE;
        if (TRUE == taller) {
            switch (T->bf) {
            case LH: T->bf = EH; taller = FALSE; break;//原左高,变等高
            case EH: T->bf = RH; taller = TRUE; break;//原等高,变右高
            case RH: RightBalance(T); taller = FALSE; break;//原右高,右平衡处理
            }
        }
    }
    return TRUE;
}

//平衡二叉树的删除结点
Status DeleteAVL(BBSTree &t, RcdType e, Status &shorter)
{
    //当被删结点有两个孩子,其前驱结点是左孩子时flag=1
    int flag = 0;
    if (t == NULL) {
        return FALSE;
    }
    else if (e == t->data) {
        BBSTree q = NULL;
        //该结点只有一个孩子,将左子树取代该结点
        if (t->lchild == NULL) {
            q = t;
            t = t->rchild;
            free(q);
            shorter = TRUE;
        }
        else if (t->rchild == NULL) {
            q = t;
            t = t->lchild;
            free(q);
            shorter = TRUE;
        }
        //被删结点有两个孩子,则找到其前驱结点并将前驱结点的值赋,删除前驱结点
        else {
            q = t->lchild;
            while (q->rchild)
                q = q->rchild;
            t->data = q->data;
            if (t->lchild->data == q->data)
                flag = 1;
            DeleteAVL(t->lchild, q->data, shorter);
            if (flag == 1) {
                BBSTree r = t->rchild;
                if (NULL == r)
                    t->bf = 0;
                else {
                    if (r->bf == EH)
                        t->bf = -1;
                    else
                        RightBalance(t);
                }
            }
        }
    }
    else if (e < t->data) {
        if (!DeleteAVL(t->lchild, e, shorter))
            return FALSE;
        //删除完结点之后,重调结点的平衡因子
        if (shorter && (flag == 0)) {
            switch (t->bf) {
            case LH:
                t->bf = EH;shorter = TRUE;
                break;
            case EH:
                t->bf = RH;shorter = FALSE;
                break;
            case RH:
                //右平衡处理
                RightBalance(t);
                if (t->rchild->bf == EH)
                    shorter = FALSE;
                else
                    shorter = TRUE;
                break;
            }
        }
    }
    else if (e > t->data) {
        //右子树中继续查找
        if (!DeleteAVL(t->rchild, e, shorter))
            return FALSE;
        //重调结点的平衡因子
        if (shorter && (flag == 0)) {
            switch (t->bf) {
            case LH:
                LeftBalance(t);
                if (t->lchild->bf == EH)
                    shorter = FALSE;
                else
                    shorter = TRUE;
                break;
            case EH:
                t->bf = LH;shorter = FALSE;
                break;
            case RH:
                t->bf = EH;shorter = TRUE;
                break;
            }
        }
        if (flag == 1) {
            int ldepth = BBSTreeDepth(t->lchild);
            int rdepth = BBSTreeDepth(t->rchild);
            t->bf = ldepth - rdepth;
        }
    }
    return TRUE;
}

//根据输入的数据建一棵平衡二叉树
void MakeBBSTree(BBSTree &T) {
    int a;
    Status taller = TRUE;
    scanf("%d", &a);
    while (a != 0) {
        InsertAVL(T, a, taller);
        scanf("%d", &a);
    }
}

//递归先序遍历
Status PreOrderTraverse(BBSTree T)
{
    if (NULL == T) return OK;
    printf("%d ", T->data);
    PreOrderTraverse(T->lchild);
    PreOrderTraverse(T->rchild);
}

//递归中序遍历
Status InOrderTraverse(BBSTree T)
{
    if (NULL == T) return OK;
    InOrderTraverse(T->lchild);
    printf("%d ", T->data);
    InOrderTraverse(T->rchild);
}

//递归后序遍历
Status PosOrderTraverse(BBSTree T)
{
    if (NULL == T) return OK;
    PosOrderTraverse(T->lchild);
    PosOrderTraverse(T->rchild);
    printf("%d ", T->data);
}
//层次遍历
void LevelOrderTraverse_I(BBSTree &T)
{
    if (T == NULL) return;
    BBSTree p = T;
    LQueue q;
    InitQueue_LQ(q);
    printf("%d ", p->data);
    EnQueue_LQ(q, p);
    while (DeQueue_LQ(q, p)) {
        if (p->lchild) {
            printf("%d ", p->lchild->data);
            EnQueue_LQ(q, p->lchild);
        }
        if (p->rchild) {
            printf("%d ", p->rchild->data);
            EnQueue_LQ(q, p->rchild);
        }
    }
}
//凹入表输出平衡二叉树
void PrintTree(BBSTree T, int nlayer)
{
    if (T == NULL) return;
    for (int i = 0; i < nlayer; i++) {
        printf("  ");
        if (i == nlayer - 1)
            printf("|--- ");
    }
    printf("%d(%d)\n", T->data, T->bf);
    PrintTree(T->lchild, nlayer + 1);
    PrintTree(T->rchild, nlayer + 1);
}

//括号表示法输出平衡二叉树
void BraNotationPrint(BBSTree T) {
    if (T == NULL) {
        printf("#");
        return;
    }
    printf("%d", T->data);
    if (!T->lchild && !T->rchild)
        return;
    else {
        printf("(");
        if (T->lchild)
            BraNotationPrint(T->lchild);
        else 
            printf("#");
        printf(",");
        if (T->rchild)
            BraNotationPrint(T->rchild);
        else 
            printf("#");
        printf(")");
    }
}

//分割树
void SplitBBSTree(BBSTree T, BBSTree &T1, BBSTree &T2, int x)
{
    Status taller = FALSE;
    if (T->data <= x) 
        InsertAVL(T1, T->data, taller);
    else
        InsertAVL(T2, T->data, taller);
    if (T->lchild) SplitBBSTree(T->lchild, T1, T2, x);
    if (T->rchild) SplitBBSTree(T->rchild, T1, T2, x);
}
//合并树
void MergeBBSTree(BBSTree &T1, BBSTree &T2)
{
    Status taller = TRUE;
    if (T2 != NULL) {
        MergeBBSTree(T1, T2->lchild);
        InsertAVL(T1, T2->data, taller);
        MergeBBSTree(T1, T2->rchild);
    }
}
//求平衡二叉树的叶子结点
void leaves(BBSTree T)
{
    if (T == NULL) return;
    if (T->lchild == NULL && T->rchild == NULL)
        printf("%d ", T->data);
    leaves(T->lchild);
    leaves(T->rchild);
}
//销毁平衡二叉树
void DestroyAVL(BBSTree &T)
{
    if (T) {
        DestroyAVL(T->lchild);
        DestroyAVL(T->rchild);
        free(T);
        T = NULL;
    }
}

void menu()
{
    printf("****************************\n");
    printf("*     1.建立平衡二叉树     *\n");
    printf("*     2.插入结点           *\n");
    printf("*     3.删除结点           *\n");
    printf("*     4.查找结点           *\n");
    printf("*     5.遍历平衡二叉树     *\n");
    printf("*     6.求叶子结点         *\n");
    printf("*     7.平衡二叉树的深度   *\n");
    printf("*     8.合并平衡二叉树     *\n");
    printf("*     9.分裂平衡二叉树     *\n");
    printf("*     10.销毁平衡二叉树    *\n");
    printf("*     11.更换平衡二叉树    *\n");
    printf("*     0.退出程序           *\n");
    printf("****************************\n");
}

int main()
{
    int select, case2;
    BBSTree T = NULL, T1 = NULL, T2 = NULL, T3 = NULL;
    Status taller = TRUE;
    printf("*         数据结构课程设计平衡二叉树         *\n");
    while (1) {
        menu();
        printf("\n请选择:");
        scanf("%d", &select);
        switch (select)
        {
        case 0:
            DestroyAVL(T);
            DestroyAVL(T1);
            DestroyAVL(T2);
            return 0;
            break;
        case 1:
            printf("请输入整型数据(0退出)\n");
            MakeBBSTree(T);
            break;
        case 2:
            printf("请输入插入的整型数据:");
            scanf("%d", &case2);
            if (SearchAVL(T, case2))
                printf("插入失败\n");
            else {
                InsertAVL(T, case2, taller);
                printf("插入成功\n");
            }
            break;
        case 3:
            printf("请输入删除的整型数据:");
            scanf("%d", &case2);
            if (SearchAVL(T, case2)) {
                DeleteAVL(T, case2, taller);
                printf("删除成功\n");
            }
            else
                printf("无此数据,删除失败\n");
            break;
        case 4:
            printf("请输入要查找的整型数据:");
            scanf("%d", &case2);
            if (SearchAVL(T, case2) == 0)
                printf("无此整型数据\n");
            else
                printf("查找成功,存在%d\n", case2);
            break;
        case 5:
            printf("\n前序遍历:");
            PreOrderTraverse(T);
            printf("\n中序遍历:");
            InOrderTraverse(T);
            printf("\n后序遍历:");
            PosOrderTraverse(T);
            printf("\n层次遍历:");
            LevelOrderTraverse_I(T);
            printf("\n括号表示法打印:");
            BraNotationPrint(T);
            printf("\n凹入表打印:\n");
            PrintTree(T, 0);
            break;
        case 6:printf("\n叶子结点是:"); leaves(T); printf("\n"); break;
        case 7:printf("\n树的深度是%d\n", BBSTreeDepth(T)); break;
        case 8:
            printf("请输第二棵树的整型数据:(0退出)\n");
            MakeBBSTree(T3);
            printf("\n凹入表打印:\n");
            PrintTree(T, 0);
            printf("\n凹入表打印:\n");
            PrintTree(T3, 0);
            MergeBBSTree(T, T3);
            DestroyAVL(T3);
            printf("合并后:\n");
            PrintTree(T, 0); break;
        case 9:
            if (T == NULL) printf("空树,无法分割\n");
            else {
                int xx;
                printf("输入x值:\n");
                scanf("%d", &xx);
                SplitBBSTree(T, T1, T2, xx);
                printf("分割后:\n");
                PrintTree(T1, 0);
                PrintTree(T2, 0);

                printf("请选择要操作的平衡二叉树:1 or 2\n");
                while (1) {
                    scanf("%d", &xx);
                    DestroyAVL(T);
                    if (xx == 1) {
                        T = T1;
                        T1 = NULL;
                        DestroyAVL(T2);
                        break;
                    }
                    else if (xx == 2) {
                        T = T2;
                        T2 = NULL;
                        DestroyAVL(T1);
                        break;
                    }
                    else
                        printf("选择无效,重新输入:");

                }
            }
            break;
        case 10:
            if (T == NULL) {
                printf("空树,无法销毁\n");
            }
            else {
                DestroyAVL(T);
                if (T == NULL)
                    printf("销毁成功\n");
            }
            break;
        default:
            printf("输入错误,重新输入\n");
            break;
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值