平衡二叉树代码实现

完整代码实现

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

//平衡二叉树的结点
typedef struct AVLNode {
    int key; //关键字
    struct AVLNode *lChild; //左子树
    struct AVLNode *rChild; //右子树
} AVLNode;

//平衡二叉树
typedef struct AVL {
    AVLNode *root;
} AVL;

//初始化
void initAVL(AVL *avl) {
    avl->root = NULL;
}

//更新高度
int getHeight(const AVLNode *p) {
    if (p) {
        return fmax(getHeight(p->lChild), getHeight(p->rChild)) + 1;
    }
    return 0;
}

//左旋
void leftRotate(AVLNode **pp) {
    AVLNode *p = *pp;
    *pp = (*pp)->rChild;
    p->rChild = (*pp)->lChild;
    (*pp)->lChild = p;
}

//右旋
void rightRotate(AVLNode **pp) {
    AVLNode *p = *pp;
    *pp = (*pp)->lChild;
    p->lChild = (*pp)->rChild;
    (*pp)->rChild = p;
}

//调整平衡
void adjustBalance(AVLNode **pp, const int key) {
    if ((*pp)->key > key) {
        if (getHeight((*pp)->lChild) - getHeight((*pp)->rChild) == 2) {
            if (getHeight((*pp)->lChild->lChild) - getHeight((*pp)->lChild->rChild) == -1) {
                leftRotate(&(*pp)->lChild);
            }
            rightRotate(pp);
        }
    } else {
        if (getHeight((*pp)->lChild) - getHeight((*pp)->rChild) == -2) {
            if (getHeight((*pp)->rChild->lChild) - getHeight((*pp)->rChild->rChild) == 1) {
                rightRotate(&(*pp)->rChild);
            }
            leftRotate(pp);
        }
    }
}

//插入结点
void insertAVL(AVLNode **pp, const int key) {
    if (!*pp) {
        *pp = (AVLNode *) malloc(sizeof(AVLNode));
        (*pp)->key = key;
        (*pp)->lChild = (*pp)->rChild = NULL;
    } else if ((*pp)->key > key) {
        insertAVL(&(*pp)->lChild, key);
        adjustBalance(pp, key);
    } else if ((*pp)->key < key) {
        insertAVL(&(*pp)->rChild, key);
        adjustBalance(pp, key);
    } else {
        printf("结点已存在!\n");
    }
}

//删除结点
void deleteAVL(AVLNode **pp, int key) {
    if (!*pp) {
        printf("结点不存在!\n");
    } else if ((*pp)->key > key) {
        deleteAVL(&(*pp)->lChild, key);
        adjustBalance(pp, key);
    } else if ((*pp)->key < key) {
        deleteAVL(&(*pp)->rChild, key);
        adjustBalance(pp, key);
    } else {
        AVLNode *p = *pp;
        if ((*pp)->lChild && (*pp)->rChild) {
            p = (*pp)->lChild;
            while (p->rChild) {
                p = p->rChild;
            }
            key = p->key;
            deleteAVL(pp, p->key);
            (*pp)->key = key;
        } else if ((*pp)->lChild) {
            *pp = (*pp)->lChild;
            free(p);
        } else if ((*pp)->rChild) {
            *pp = (*pp)->rChild;
            free(p);
        } else {
            *pp = NULL;
            free(p);
        }
    }
}

//中序遍历
void inorderAVL(const AVLNode *p) {
    if (p) {
        inorderAVL(p->lChild);
        printf("%-10d%-10d%-10d", p->key, getHeight(p), getHeight(p->lChild) - getHeight(p->rChild));
        if(p->lChild){
            printf("%-10d",p->lChild->key);
        } else{
            printf("%-10s","无");
        }
        if(p->rChild){
            printf("%-10d\n",p->rChild->key);
        } else{
            printf("%-10s\n","无");
        }
        inorderAVL(p->rChild);
    }
}

//测试代码
void test() {
    AVL avl;
    initAVL(&avl);
    int sel, key;
    while (true) {
        printf("1.插入数据\n2.删除数据\n3.打印信息\n");
        scanf("%d", &sel);
        switch (sel) {
            case 1: {
                printf("关键字:");
                scanf("%d", &key);
                insertAVL(&avl.root, key);
                break;
            }
            case 2: {
                printf("关键字:");
                scanf("%d", &key);
                deleteAVL(&avl.root, key);
                break;
            }
            case 3: {
                printf("%-10s%-10s%-10s%-10s%-10s\n", "关键字", "高度", "平衡因子", "左孩子", "右孩子");
                inorderAVL(avl.root);
                break;
            }
            default: {
                return;
            }
        }
        system("pause");
        system("cls");
    }
}

int main() {
    test();
    return 0;
}
  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花园宝宝没有天线

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值