栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

数据结构

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据结构

数据结构总目录
平衡二叉树

平衡二叉树(英文名也称为 AVL 树),是在排序二叉树的结构基础上进行优化的一种二叉树,该树的性质是任意结点的左右子树高度相差都不超过1

1. 图文解析

在平衡二叉树中,主要分为四种需要调整平衡状态的情况
(1)A结点的平衡因子 = 【A结点的左子树高度】 - 【A结点的右子树高度】 = 2,发生不平衡,且新插入的结点为左孩子(A),则右旋转该子树,并更新旋转后的结点高度。

(2)A结点的平衡因子 = 【A结点的左子树高度】 - 【A结点的右子树高度】 = -2,发生不平衡,且新插入的结点为右孩子(C),则左旋转该子树,并更新旋转后的结点高度。

(3)A结点的平衡因子 = 【A结点的左子树高度】 - 【A结点的右子树高度】 = 2,发生不平衡,且新插入的结点为右孩子(B),则先左旋转p结点,再右旋转node结点,完成平衡操作。

(4)A结点的平衡因子 = 【A结点的左子树高度】 - 【A结点的右子树高度】 = -2,发生不平衡,且新插入的结点为左孩子(B),则先右旋转p结点,再左旋转node结点,完成平衡操作。

2. 源代码
#include
#include
#define max(a,b) ((a>b)?(a):(b))

typedef char DataType;
typedef struct AVLNode
{
    DataType data;          // 数据域
    struct AVLNode *lchild; // 指针域,指向左孩子结点
    struct AVLNode *rchild; // 指针域,指向右孩子结点
    int height;             // 表示当前结点作为根结点子树的高度
}AVLNode, *AVLTree;

// 初始化
void InitAVLTree(AVLTree *T)
{
    (*T) = NULL;   // 初始化根节点为空
    printf("二叉树已初始化!n");
}

// 获取子树高度
int getHeight(AVLNode *node)
{
    return node == NULL ? 0: node->height;
}

// 右旋转
AVLNode* Rotate_R(AVLNode *node)
{
    AVLNode *p = node->lchild;
    node->lchild = p->rchild;
    p->rchild = node;

    // 更新高度(注意顺序)
    node->height = max(getHeight(node->lchild), getHeight(node->rchild)) + 1;
    p->height = max(getHeight(p->lchild), getHeight(p->rchild)) + 1;

    return p;
}

// 左旋转
AVLNode* Rotate_L(AVLNode *node)
{
    AVLNode *p = node->rchild;
    node->rchild = p->lchild;
    p->lchild = node;

    // 更新高度(注意顺序)
    node->height = max(getHeight(node->lchild), getHeight(node->rchild)) + 1;
    p->height = max(getHeight(p->lchild), getHeight(p->rchild)) + 1;

    return p;
}

// 先左旋转,再右旋转
AVLNode* Rotate_LR(AVLNode *node)
{
    AVLNode *p = node->lchild;
    node->lchild = Rotate_L(p);
    return Rotate_R(node);
}

// 先右旋转,再左旋转
AVLNode* Rotate_RL(AVLNode *node)
{
    AVLNode *p = node->rchild;
    node->rchild = Rotate_R(p);
    return Rotate_L(node);
}

// 计算平衡因子
int getBalance(AVLNode *node)
{
    if (node == NULL)
    {
        return 0;
    }
    return getHeight(node->lchild) - getHeight(node->rchild);
}

// 排序二叉树的插入操作
void AVLTreeInsert(AVLTree *T, DataType x)
{
    if ((*T) == NULL)
    {
        // 如果当前二叉树结点为空, 即是插入的位置,则分配新的结点空间
        (*T) = (AVLNode *)malloc(sizeof(AVLNode));
        (*T)->data = x;
        (*T)->height = 1;
        (*T)->lchild = (*T)->rchild = NULL;
    }
    else if (x < (*T)->data)
    {
        // 递归左子树查找插入位置
        AVLTreeInsert(&(*T)->lchild, x);
    }
    else if(x > (*T)->data)
    {
        // 递归右子树查找插入位置
        AVLTreeInsert(&(*T)->rchild, x);
    }
    else
    {
        printf("插入失败!存在相同数据!n");
        return;
    }

    // 在递归插入过程中更新父结点的高度
    (*T)->height = max(getHeight((*T)->lchild), getHeight((*T)->rchild)) + 1;
    
    // 获取平衡因子
    int balance = getBalance((*T));
    
    printf("结点:%c, 高度 = %d, 平衡因子 = %dt",(*T)->data, (*T)->height, balance);
    
    // 根据平衡因子选择 旋转方式
    if (balance > 1 && x < (*T)->lchild->data)
    {
        printf("右旋");
        (*T) = Rotate_R((*T));
    }
    else if (balance < -1 && x > (*T)->rchild->data)
    {
        printf("左旋");
        (*T) = Rotate_L((*T));
    }
    else if (balance > 1 && x > (*T)->lchild->data)
    {
        printf("左右旋");
        (*T) = Rotate_LR((*T));
    }
    else if (balance < -1 && x < (*T)->rchild->data)
    {
        printf("右左旋");
        (*T) = Rotate_RL((*T));
    }
    printf("n");
}

// 先序遍历
void PreOrderTraverse(AVLTree T)
{
    if (T)
    {
        printf("%c ", T->data);
        PreOrderTraverse(T->lchild);
        PreOrderTraverse(T->rchild);
    }
}

int main()
{
    AVLTree T;
    InitAVLTree(&T);
    DataType x;
    while (1)
    {
        printf("输入插入数据:");
        fflush(stdin);
        scanf("%c", &x);
        if (x == '#')
        {
            break;
        }
        AVLTreeInsert(&T, x);
        printf("先序遍历:");
        PreOrderTraverse(T);
        printf("n");
    }
    system("pause");
    return 0;
}
3. 测试结果

右旋转

左旋转

先左旋转,再右旋转

先右旋转,在左旋转

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/982144.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号