重学数据结构008——AVL树

之前学习了二叉查找树的及相关操作。二叉查找树的大部分主要操作的复杂度都是O(logN)量级的。现在考虑这样一种情况:通过集合{3,2,4,1,0,-1,-2,-3,-4,-4}中的元素来构建二叉查找树,得到的树如图所示:

image

    如果现在我们需要查找元素-4,那么时间复杂度还是是O(logN)吗?有个更加极端的例子,假设数据集是{6,5,3,1,0,-1,-2,-3,-4,-4}呢?再去查找元素-4,其复杂度已经是O(N)了。也就是说,二叉查找树的查找优势完全不复存在了。在这样的情况下,以前的牛人们又想出了别的办法:让二叉查找树除了满足现有条件外,添加平衡条件,形成平衡二叉树。AVL树是其中一种典型的平衡二叉树,

    AVL树是带有平衡条件的二叉查找树。在满足所有二叉查找树条件下,还加入了平衡条件:AVl树的每个节点的左右子树的高度差必须<=1。 在我使用的这本教材中,定义空树的高度为-1,一个节点的树的高度定义为0。

   为了满足平衡条件,AVL树的基本操作一般涉及运作同在不平衡的二叉查找树所运作的同样的算法。但是要进行预先或随后做一次或多次所谓的"AVL旋转"。

涉及到的几种情况如下图所示:

Tree_Rebalancing

AVL树的基本操作代码如下:

#include <stdio.h> 
#include <stdlib.h> 
 
#define MAX(X,Y) ((X > Y) ? X : Y) 
 
typedef int ElementType; 
typedef struct AvlNode *Position; 
typedef struct AvlNode *AvlTree; 
 
/************************************************************************/ 
/* Avl树的数据结构定义以及节本操作定义                                  */ 
/************************************************************************/ 
 
struct AvlNode  
{ 
    ElementType Element; 
    int Height; 
    AvlTree Left,Right; 
}; 
 
 
AvlTree MakeEmpty(AvlTree T);                                /*清空Avl树*/ 
 
Position Find(ElementType X, AvlTree T);       /*在Avl树中查找指定的元素*/ 
 
Position FindMax(AvlTree T);                     /*在Avl树中查找最大元素*/ 
 
Position FindMin(AvlTree T);                     /*在Avl树中查找最小元素*/ 
 
AvlTree Insert(ElementType X, AvlTree T);        /*在Avl树中插入指定元素*/ 
 
AvlTree Delete(ElementType X, AvlTree T);        /*在Avl树中删除指定元素*/ 
 
ElementType Retrieve(Position P);                 /*获取指定节点的元素值*/ 
 
int Height(Position P);                           /*获得指定节点的高度值*/ 
 
Position SingleRotateWithLeft(Position P);                    /*单右旋转*/ 
 
Position SingleRotateWithRight(Position P);                   /*单左旋转*/ 
 
Position DoubleRotateWithLeft(Position P);                  /*双左右旋转*/ 
 
Position DoubleRotateWithRight(Position P);                 /*双右左旋转*/ 
 
int main(void)  
{ 
 
    return 0; 
} 
 
/************************************************************************/ 
/* 清空AVL树的操作与清空普通二叉树相同                                  */ 
/************************************************************************/ 
AvlTree MakeEmpty(AvlTree T)  
{ 
    if (!T) 
    { 
        MakeEmpty(T->Left); 
        MakeEmpty(T->Right); 
        free(T); 
    } 
    return NULL; 
} 
 
/************************************************************************/ 
/*在Avl树中查找指定的元素,与二叉查找树的操作相同                        */ 
/************************************************************************/ 
Position Find(ElementType X, AvlTree T) 
{ 
    if (T == NULL) 
    { 
        return NULL; 
    }  
    else 
    { 
        if (X < T->Element) 
        { 
            return Find(X,T->Left); 
        } 
        else if(X > T->Element) 
        { 
            return Find(X, T->Right); 
        } 
        else 
        { 
            return T; 
        } 
    } 
} 
 
/************************************************************************/ 
/* 在Avl树中查找最大值(递归写法)                                        */ 
/************************************************************************/ 
Position FindMax(AvlTree T) 
{ 
    if (T == NULL) 
    { 
        return NULL; 
    }  
    else 
    { 
        if (T->Right == NULL) 
        { 
            return NULL; 
        }  
        else 
        { 
            return FindMax(T->Right); 
        } 
    } 
} 
 
 
/************************************************************************/ 
/* 在Avl树中查找最小值(非递归写法)                                      */ 
/************************************************************************/ 
Position FindMin(AvlTree T) 
{ 
    if (T == NULL) 
    { 
        return NULL; 
    } 
    else 
    { 
        while (T->Left != NULL) 
        { 
            T = T->Left; 
        } 
        return T; 
    } 
} 
 
/************************************************************************/ 
/* 返回指定节点的高度信息                                               */ 
/************************************************************************/ 
int Height(Position P)  
{ 
    if (P == NULL) 
    { 
        return -1; 
    } 
    else 
    { 
        return P->Height; 
    } 
} 
 
/************************************************************************/ 
/* 单旋转:右旋转                                                       */ 
/* 使用条件:这个函数只适合当P有左子树时调用;                          */ 
/* 作用:在P和其左子树根节点之间执行一次单右旋转                      */ 
/************************************************************************/ 
Position SingleRotateWithLeft(Position P) 
{ 
    Position LChild = P->Left; 
    P->Left = LChild->Right;           /*将P的左孩子设置成LChild的右孩子*/ 
    LChild->Right = P; 
 
    P->Height = MAX(Height(P->Left),Height(P->Right)) + 1;/*更新高度信息*/ 
    LChild->Height = MAX(Height(LChild->Left),P->Height) + 1; 
 
    return LChild;                                          /*新的根节点*/    
} 
 
 
/************************************************************************/ 
/* 单旋转:左旋转                                                       */ 
/* 使用条件:这个函数只适合当P有右子树时调用;                           */ 
/* 作用:在P和其右子树根节点之间执行一次单左旋转                      */ 
/************************************************************************/ 
Position SingleRotateWithRight(Position P) 
{ 
    Position RChild = P->Right;        /*将P的右孩子设置成RChild的右孩子*/ 
    P->Right = RChild->Left;                                 
    RChild->Left = P; 
 
    P->Height = MAX(Height(P->Left),Height(P->Right)) + 1;/*更新高度信息*/ 
    RChild->Height = MAX(Height(RChild->Right),P->Height) + 1; 
    return RChild;                                          /*新的根节点*/ 
} 
 
 
/************************************************************************/ 
/* 双旋转:左右旋转                                                     */ 
/* 使用条件:适合于当P有左孩子,而左孩子有右孩子                        */ 
/* 作用:*/ 
/************************************************************************/ 
Position DoubleRotateWithLeft(Position P) 
{ 
    P->Left = SingleRotateWithRight(P->Left);             /*先进行左旋转*/ 
    return SingleRotateWithLeft(P);                       /*再进行又旋转*/ 
} 
 
 
/************************************************************************/ 
/* 双旋转:右左旋转                                                     */ 
/* 使用条件:适合于当P有右孩子,而右孩子有左孩子                        */ 
/* 作用:*/ 
/************************************************************************/ 
Position DoubleRotateWithRight(Position P) 
{ 
    P->Right = SingleRotateWithLeft(P->Right);            /*先进行右旋转*/ 
    return SingleRotateWithRight(P);                      /*再进行左旋转*/ 
} 
 
/************************************************************************/ 
/* AVL树插入操作                                                        */ 
/************************************************************************/ 
AvlTree Insert(ElementType X, AvlTree T) 
{ 
    /*如果T是一棵空树,那么创建一个节点作为树的根节点*/ 
    if (T == NULL) 
    { 
        T = malloc(sizeof(struct AvlNode)); 
        if(T == NULL) 
        { 
            fprintf(stderr,"Out of space!"); 
        } 
        else 
        { 
            T->Element = X; 
            T->Left = NULL; 
            T->Right = NULL; 
            T->Height = 0; 
        } 
    }else 
    { 
        if (X < T->Element) 
        { 
            T->Left = Insert(X,T->Left); 
            /*判断是否打破了破了平衡条件*/ 
            if (Height(T->Left) - Height(T->Right) == 2) 
            { 
                /*判断是四种情况中的哪一种情况*/ 
                if (X < T->Left->Element) 
                { 
                    T = SingleRotateWithLeft(T); 
                } 
                else if (X > T->Left->Element) 
                { 
                    T = DoubleRotateWithLeft(T); 
                } 
            } 
        } 
        else if (X > T->Element) 
        { 
            T->Right = Insert(X,T->Right); 
            if (Height(T->Right) - Height(T->Left) == 2) 
            { 
                if(X < T->Right->Element) 
                { 
                    T = DoubleRotateWithRight(T); 
                } 
                else if (X > T->Right->Element) 
                { 
                    T = SingleRotateWithRight(T); 
                } 
            } 
        } 
        else 
        { 
            /*元素已经存在于AVL树中,因此不需要再做别的工作*/ 
        } 
 
        /*更新数的高度信息*/ 
        T->Height = MAX(Height(T->Left),Height(T->Right)) + 1; 
 
 
     
    } 
    return T; 
} 
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
健身国际俱乐部系统是一种专为健身俱乐部设计的管理软件,它通过集成多种功能来提高俱乐部的运营效率和服务质量。这类系统通常包含以下几个核心模块: 1. **会员管理**:系统能够记录会员的基本信息、会籍状态、健身历史和偏好,以及会员卡的使用情况。通过会员管理,俱乐部可以更好地了解会员需求,提供个性化服务,并提高会员满意度和忠诚度。 2. **课程预约**:会员可以通过系统预约健身课程,系统会提供课程时间、教练、地点等详细信息,并允许会员根据个人时间表进行预约。这有助于俱乐部合理安排课程,避免资源浪费。 3. **教练管理**:系统可以管理教练的个人信息、课程安排、会员反馈等,帮助俱乐部评估教练表现,优化教练团队。 4. **财务管理**:包括会员卡销售、课程费用、私教费用等财务活动的记录和管理,确保俱乐部的财务透明度和准确性。 5. **库存管理**:对于俱乐部内的商品销售,如健身装备、营养补充品等,系统能够进行库存管理,包括进货、销售、库存盘点等。 6. **数据分析**:系统能够收集和分析会员活动数据,为俱乐部提供业务洞察,帮助俱乐部制定更有效的营销策略和业务决策。 7. **在线互动**:一些系统还提供在线平台,让会员可以查看课程、预约私教、参与社区讨论等,增强会员之间的互动和俱乐部的社区感。 8. **移动应用**:随着移动设备的普及,一些健身俱乐部系统还提供移动应用,方便会员随时随地管理自己的健身计划。 9. **安全性**:系统会确保所有会员信息的安全,采取适当的数据加密和安全措施,保护会员隐私。 10. **可扩展性**:随着俱乐部业务的扩展,系统应该能够轻松添加新的功能和服务,以适应不断变化的市场需求。 健身国际俱乐部系统的选择和实施,需要考虑俱乐部的具体需求、预算和技术能力,以确保系统能够有效地支持俱乐部的运营和发展。通过这些系统的实施,健身俱乐部能够提供更加专业和高效的服务,吸引和保留更多的会员,从而在竞争激烈的
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值