C语言数据结构学习笔记(23)-平衡二叉树-AVL树创建及删除

/*平衡二叉树-AVL树创建及删除
请输入待创建AVL树结点个数:10
请依次输入结点信息:3
Root = 3
请依次输入结点信息:2
Root = 3
请依次输入结点信息:1
Root = 2
请依次输入结点信息:4
Root = 2
请依次输入结点信息:5
Root = 2
请依次输入结点信息:6
Root = 4
请依次输入结点信息:7
Root = 4
请依次输入结点信息:10
Root = 4
请依次输入结点信息:9
Root = 4
请依次输入结点信息:8
Root = 4
中序:1(1)2(2)3(1)4(4)5(1)6(2)7(3)8(1)9(2)10(1)
层序:4(4)2(2)7(3)1(1)3(1)6(2)9(2)5(1)8(1)10(1)
高度:4
请依次输入待删除的结点信息:1

中序:2(2)3(1)4(4)5(1)6(2)7(3)8(1)9(2)10(1)
层序:4(4)2(2)7(3)3(1)6(2)9(2)5(1)8(1)10(1)
高度:4
请依次输入待删除的结点信息:2

中序:3(1)4(3)5(1)6(2)7(4)8(1)9(2)10(1)
层序:7(4)4(3)9(2)3(1)6(2)8(1)10(1)5(1)
高度:4
请依次输入待删除的结点信息:3

中序:4(1)5(2)6(1)7(3)8(1)9(2)10(1)
层序:7(3)5(2)9(2)4(1)6(1)8(1)10(1)
高度:3
请依次输入待删除的结点信息:4

中序:5(2)6(1)7(3)8(1)9(2)10(1)
层序:7(3)5(2)9(2)6(1)8(1)10(1)
高度:3
请依次输入待删除的结点信息:5

中序:6(1)7(3)8(1)9(2)10(1)
层序:7(3)6(1)9(2)8(1)10(1)
高度:3
请依次输入待删除的结点信息:-1
请按任意键继续. . .
*/
# include <stdio.h>
# include <stdlib.h>
# define MAX_SIZE 50
# define Max(x, y) ((x) > (y) ? (x) : (y))
typedef int ElemType;
typedef struct AVLTreeNode{
    ElemType data;
    AVLTreeNode * lchild, * rchild;
    int high;
}AVLNode, *AVLTree;
//创建结点
AVLTree CreateNode(ElemType data);
//插入结点
void InsertNode(AVLTree * pRoot, ElemType data);
//获取数的高度
int GetHeight(AVLTree Root);
//LL右旋
void LL_Rotate(AVLTree * pRoot);
//RR左旋
void RR_Rotate(AVLTree * pRoot);
//LR左右旋
void LR_Rotate(AVLTree * pRoot);
//RL右左旋
void RL_Rotate(AVLTree * pRoot);
//中序遍历
void InOrderTree(AVLTree Root);
//层序遍历
void LevelOrderTree(AVLTree Root);
//查找最大值节点
AVLTree FindMax(AVLTree root);
//查找最小值节点
AVLTree FindMin(AVLTree root);
//删除结点
void DeleteAVL(AVLTree * proot, int data);

int main(void)
{    
    int num;
    ElemType arr[MAX_SIZE];
    printf("请输入待创建AVL树结点个数:");
    scanf("%d", &num);
    AVLTree Root = NULL;
    for(int i = 0; i < num; i++)
    {
        printf("请依次输入结点信息:");
        scanf("%d", &arr[i]);
        InsertNode(&Root, arr[i]);
        printf("Root = %d\n", Root->data);
    }
    printf("中序:");
    InOrderTree(Root);
    printf("\n层序:");
    LevelOrderTree(Root);
    printf("\n高度:");
    printf("%d\n",Root->high);
    int a;
    printf("请依次输入待删除的结点信息:");
    while(~scanf("%d", &a) && a != -1)
    {
        DeleteAVL(&Root, a);
        printf("\n中序:");
        InOrderTree(Root);
        printf("\n层序:");
        LevelOrderTree(Root);
        printf("\n高度:");
        printf("%d\n",Root->high);
        printf("请依次输入待删除的结点信息:");
    }
    system("pause");
    return 0;
}
//创建结点
AVLTree CreateNode(ElemType data)
{    
    AVLTree pNew = (AVLTree)malloc(sizeof(AVLNode));
    if(!pNew)
        exit(-1);
    pNew->data = data;
    pNew->lchild = NULL;
    pNew->rchild = NULL;
    pNew->high = 0;
    return pNew;
}
//插入结点
void InsertNode(AVLTree * pRoot, ElemType data)
{    
    if(NULL == (*pRoot))
    {
        *pRoot = CreateNode(data);
    }
    else
    {
        if(data < (*pRoot)->data)
        {
            InsertNode(&(*pRoot)->lchild, data);
            if(GetHeight((*pRoot)->lchild) - GetHeight((*pRoot)->rchild) == 2)
            {    
                if(data < (*pRoot)->lchild->data)
                    LL_Rotate(pRoot);
                else
                {    
                    LR_Rotate(pRoot);
                }
            }
        }
        else if(data > (*pRoot)->data)
        {
            InsertNode(&(*pRoot)->rchild, data);
            if(GetHeight((*pRoot)->rchild) - GetHeight((*pRoot)->lchild) == 2)
            {    
                if(data > (*pRoot)->rchild->data)
                    RR_Rotate(pRoot);
                else
                {    
                    RL_Rotate(pRoot);
                }
            }
        }
        else
        {
            (*pRoot)->data = data;
        }
    }
    (*pRoot)->high = Max(GetHeight((*pRoot)->lchild), GetHeight((*pRoot)->rchild)) + 1;
}
//LL右旋
void LL_Rotate(AVLTree * pRoot)
{
    AVLTree p = (*pRoot)->lchild;
    (*pRoot)->lchild = p->rchild;
    p->rchild = *pRoot;
    (*pRoot)->high = Max(GetHeight((*pRoot)->lchild), GetHeight((*pRoot)->rchild)) + 1;
    p->high = Max(GetHeight(p->lchild), GetHeight(p->rchild)) + 1;
    *pRoot = p;
}
//RR左旋
void RR_Rotate(AVLTree * pRoot)
{
    AVLTree p = (*pRoot)->rchild;
    (*pRoot)->rchild = p->lchild;
    p->lchild = *pRoot;
    (*pRoot)->high = Max(GetHeight((*pRoot)->lchild), GetHeight((*pRoot)->rchild)) + 1;
    p->high = Max(GetHeight(p->lchild), GetHeight(p->rchild)) + 1;
    *pRoot = p;
}
//LR左右旋
void LR_Rotate(AVLTree * pRoot)
{
    RR_Rotate(&(*pRoot)->lchild);
    LL_Rotate(pRoot);
}
//RL右左旋
void RL_Rotate(AVLTree * pRoot)
{
    LL_Rotate(&(*pRoot)->rchild);
    RR_Rotate(pRoot);
}
//获取数的高度
int GetHeight(AVLTree Root)
{
    if(NULL == Root)  
        return 0;
    return Root->high;
}
//中序遍历
void InOrderTree(AVLTree Root)
{
    if(NULL == Root)
        return;
    InOrderTree(Root->lchild);
    printf("%d(%d)", Root->data, Root->high);
    InOrderTree(Root->rchild);
}
//层序遍历
void LevelOrderTree(AVLTree Root)
{
    AVLTree Queue[MAX_SIZE];
    int front = 0;
    int rear = 0;
    AVLTree p = NULL;
    rear = (rear + 1)%MAX_SIZE;
    Queue[rear] = Root;
    while(front != rear)
    {    
        front = (front + 1)%MAX_SIZE; 
        p = Queue[front];
        printf("%d(%d)", p->data, p->high);
        if(p->lchild)
        {
            rear = (rear + 1)%MAX_SIZE;
            Queue[rear] = p->lchild;
        }
        if(p->rchild)
        {
            rear = (rear + 1)%MAX_SIZE;
            Queue[rear] = p->rchild;
        }    
    }
}
//查找最大值节点
AVLTree FindMax(AVLTree root)
{
    if(root)
    {
        while(root->rchild)
        {
            root = root->rchild;
        }
    }
    return root;
}
//查找最小值节点
AVLTree FindMin(AVLTree root)
{
    if(root)
    {
        while(root->lchild)
        {
            root = root->lchild;
        }
    }
    return root;
}
//删除结点
void DeleteAVL(AVLTree * proot, int data)
{    
    if(NULL == *proot)
        return;
    if(data < (*proot)->data)
    {
        DeleteAVL(&(*proot)->lchild, data);
        if(GetHeight((*proot)->rchild)- GetHeight((*proot)->lchild) == 2)
        {
            if(GetHeight((*proot)->rchild->lchild) > GetHeight((*proot)->rchild->rchild))
                RL_Rotate(proot);
            else
                RR_Rotate(proot);
        }
        (*proot)->high = Max(GetHeight((*proot)->lchild), GetHeight((*proot)->rchild)) + 1;
    }
    else if(data > (*proot)->data)
    {
        DeleteAVL(&(*proot)->rchild, data);
        if(GetHeight((*proot)->lchild)- GetHeight((*proot)->rchild) == 2)
        {
            if(GetHeight((*proot)->lchild->lchild) > GetHeight((*proot)->lchild->rchild))
                LL_Rotate(proot);
            else
                LR_Rotate(proot);
        }
        (*proot)->high = Max(GetHeight((*proot)->lchild), GetHeight((*proot)->rchild)) + 1;
    }
    else
    {
        if((*proot)->lchild && (*proot)->rchild)
        {    
            if(GetHeight((*proot)->lchild) > GetHeight((*proot)->rchild))
            {
                AVLTree    Temp = FindMax((*proot)->lchild);
                (*proot)->data = Temp->data;
                DeleteAVL(&(*proot)->lchild, (*proot)->data);
            }
            else
            {
                AVLTree    Temp = FindMin((*proot)->rchild);
                (*proot)->data = Temp->data;
                DeleteAVL(&(*proot)->rchild, (*proot)->data);
            }
        
        }
        else
        {    
            AVLTree    Temp = *proot;
            if(NULL == (*proot)->lchild)
                (*proot) = (*proot)->rchild;
            else if(NULL == (*proot)->rchild)
                (*proot) = (*proot)->lchild;
            else
                (*proot) = NULL;
            free(Temp);
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值