C/C++平衡二叉树实现 —— 插入、删除、先序遍历、中序遍历、后序遍历、层序遍历(设计详解)

本文介绍了使用C++编程实现AVL树的详细步骤,包括节点插入、删除操作以及先序、中序、后序和层序遍历。代码实现了平衡二叉树的节点平衡调整,如左旋、右旋以及双旋操作,确保树的平衡。此外,还提供了完整的主函数测试案例,展示了各种操作后的结果。

输出展示:
在这里插入图片描述

相关文章目录

MFC二叉树可视化绘制 (C++)—— 插入、删除、先序遍历、中序遍历、后序遍历、层序遍历(基于平衡二叉树实现)

前言

该程序由c语言编写,可运行于vs环境下,可轻易转换成C++代码。

一、实现功能

实现操作:结点的插入、删除。
实现输出:输出先序遍历、中序遍历、后序遍历、层序遍历的结果。

二、代码设计

1. 定义平衡二叉树的结点结构

平衡二叉树的结点结构:

// 平衡二叉树的结点结构
typedef struct BiTNode
{
   
   
    int data;
    int bf;             // 平衡因子
    BiTNode* lchild, * rchild;
}BiTNode, * BiTree;

BiTree 为指向树结点的指针,用于表示树对象。

2. 定义层序遍历链队列相关结构和函数

链队列结构:

/* 链队列结点结构(用于层序遍历) */
typedef struct QNode {
   
   
    BiTree t;                   // 结点数据域
    struct QNode* next;        // 结点指针域
}QNode, * QueuePtr;

/* 链队列结构(用于层序遍历) */
typedef struct {
   
   
    QueuePtr front;     // 队首指针
    QueuePtr rear;      // 队尾指针
}LinkQueue;

初始化链队列函数、进队函数、出队函数定义:

/* 初始化链队列函数 */
Status InitQueue(LinkQueue& Q)
{
   
   
    // 创建一个带附加头结点的空链队列
    Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
    if (!Q.front) {
   
   
        return ERROR;
    }
    Q.front->next = NULL;
    return OK;
}

/* 进队函数 */
/* e:插入元素 */
Status EnQueue(LinkQueue& Q, BiTree e)
{
   
   
    // 将元素e插入到链队列中
    QueuePtr p;
    p = (QueuePtr)malloc(sizeof(QNode));
    if (!p) {
   
   
        return ERROR;
    }
    p->t = e;
    p->next = NULL;
    Q.rear->next = p;
    Q.rear = p;
    return OK;
}

/* 出队函数 */
/* e:出队元素 */
Status DeQueue(LinkQueue& Q, BiTree& e)
{
   
   
    // 出队,将出队元素放入e中
    QueuePtr p;
    if (Q.rear == Q.front) {
   
   
        return ERROR;
    }
    p = Q.front->next;
    e = p->t;
    Q.front->next = p->next;
    if (Q.rear == p) {
   
   
        Q.rear = Q.front;
    }
    free(p);
    return OK;
}
3. 定义结点旋转函数 —— 用于二叉树的结点平衡

LL调整(左单旋)、RR调整(右单旋)、LR调整(先左旋再右旋)、RL调整(先右旋再左旋)。

关于平衡二叉树的旋转问题请参考:平衡二叉树的构造过程图解

// 右旋处理,即LL调整
void R_Rotate(BiTree* p)
{
   
   
    BiTree L;
    L = (*p)->lchild;
    (*p)->lchild = L->rchild;
    L->rchild = *p;
    *p = L;
}

// 左旋处理,即RR调整
void L_Rotate(BiTree* p)
{
   
   
    BiTree R;
    R = (*p)->rchild;
    (*p)->rchild = R->lchild;
    R->lchild = *p;
    *p = R;
}

// 左平衡旋转处理,包括 LL 和 LR 调整
void LeftBalance(BiTree* T)
{
   
   
    BiTree L, Lr;
    L = (*T)->lchild;
    switch (L->bf)
    {
   
   
    case 1:        // 新结点插入在T的左孩子的左子树上,为LL型,作右旋处理即LL调整
        (*T)->bf = L->bf = 0;
        R_Rotate(T);
        break;
    case -1:        // 新结点插入在T的左孩子的右子树上,为LR型,作双旋处理
        Lr = L->rchild;
        switch (Lr->bf)
        {
   
   
        case 1:
            (*T)->bf = -1;
            L->bf = 0;
            break;
        case 0:
            (*T)->bf = L->bf = 0;
            break;
        case -1:
            (*T)->bf = 0;
            L->bf = 1;
            break;
        }
        Lr->bf = 0;
        L_Rotate(&(*T)->lchild);      // 先对T的左子树进行左旋处理即RR调整
        R_Rotate(T);                  // 再对T进行右旋处理即LL调整
    }
}

// 右平衡旋转处理,包括 RR 和 RL 调整
void RightBalance(BiTree* T)
{
   
   
    BiTree R, Rl;
    R = (*T)->rchild;
    switch (R->bf)
    {
   
   
    case -1:        // 新结点插入在T的右孩子的右子树上,为RR型,作左旋处理即RR调整
        (*T)->bf = R->bf = 0;
        L_Rotate(T);
        break;
    case 1:        // 新结点插入在T的右孩子的左子树上,为RL型,作双旋处理
        Rl = R->lchild;
        switch (Rl->bf)
        {
   
   
        case 1:
            (*T)->bf = 0;
            R->bf = -1;
            break;
        case 0:
            (*T)->bf = R->bf = 0;
            break;
        case -1:
            (*T)->bf = 1;
            R->bf = 0;
            break;
        }
        Rl->bf = 0;
        R_Rotate(&(*T)->rchild);      // 先对T的左子树进行左旋即RR调整
        L_Rotate(T);                  // 再对T进行右旋即LL调整
    }
}
4. 定义结点插入函数
// 若在平衡二叉树T中不存在和 e 具有相同数据的结点,则插入数据元素为 e 的新结点,
// 若因插入使二叉排序树失去平衡,则要作平衡调整,
// 布尔变量taller表示 T 的深度是否增加,TRUE表示增加,FALSE表示没有增加

Status InsertAVL(BiTree* T, int e, Status* taller)
{
   
   
    if (!*T)
    {
   
   
        *T = (BiTree)malloc(sizeof(BiTNode));
        if (!*T) {
   
   
            return ERROR;
        }
        else {
   
   
            (*T)->data = e;
            (*T)->lchild = (*T)->rchild = NULL;
            (*T)->bf =
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Whitemeen太白

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

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

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

打赏作者

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

抵扣说明:

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

余额充值