数据结构上机实践第14周项目1(4) - 验证算法(平衡二叉树)

简介: 数据结构上机实践第14周项目1(4) - 验证算法(平衡二叉树)

验证算法(平衡二叉树)

项目要求如下:

(1)由整数序列{43,52,75,24,10,38,67,55,63,60}构造AVL树;

(2)输出用括号法表示的AVL树;

(3)查找关键字55;

(4)分别删除43和55,输出删除后用括号法表示的二叉排序树。

实现源代码如下:

//*Copyright  (c)2017,烟台大学计算机与控制工程学院*                       
//*All rights reservrd.*                       
//*文件名称 :main.cpp*                       
//*作者:田长航*                    
//*完成时间:2017年11月29日*                        
//*版本号:v1.0*                    
//*问题描述:测试函数*                       
//*输入描述:无*                       
//*程序输出:无*
#include <stdio.h>
#include <malloc.h>
typedef int KeyType;                    //定义关键字类型
typedef char InfoType;
typedef struct node                     //记录类型
{
    KeyType key;                        //关键字项
    int bf;                             //平衡因子
    InfoType data;                      //其他数据域
    struct node *lchild,*rchild;        //左右孩子指针
} BSTNode;
void LeftProcess(BSTNode *&p,int &taller)
//对以指针p所指结点为根的二叉树作左平衡旋转处理,本算法结束时,指针p指向新的根结点
{
    BSTNode *p1,*p2;
    if (p->bf==0)           //原本左、右子树等高,现因左子树增高而使树增高
    {
        p->bf=1;
        taller=1;
    }
    else if (p->bf==-1)     //原本右子树比左子树高,现左、右子树等高
    {
        p->bf=0;
        taller=0;
    }
    else                    //原本左子树比右子树高,需作左子树的平衡处理
    {
        p1=p->lchild;       //p指向*p的左子树根结点
        if (p1->bf==1)      //新结点插入在*b的左孩子的左子树上,要作LL调整
        {
            p->lchild=p1->rchild;
            p1->rchild=p;
            p->bf=p1->bf=0;
            p=p1;
        }
        else if (p1->bf==-1)    //新结点插入在*b的左孩子的右子树上,要作LR调整
        {
            p2=p1->rchild;
            p1->rchild=p2->lchild;
            p2->lchild=p1;
            p->lchild=p2->rchild;
            p2->rchild=p;
            if (p2->bf==0)          //新结点插在*p2处作为叶子结点的情况
                p->bf=p1->bf=0;
            else if (p2->bf==1)     //新结点插在*p2的左子树上的情况
            {
                p1->bf=0;
                p->bf=-1;
            }
            else                    //新结点插在*p2的右子树上的情况
            {
                p1->bf=1;
                p->bf=0;
            }
            p=p2;
            p->bf=0;            //仍将p指向新的根结点,并置其bf值为0
        }
        taller=0;
    }
}
void RightProcess(BSTNode *&p,int &taller)
//对以指针p所指结点为根的二叉树作右平衡旋转处理,本算法结束时,指针p指向新的根结点
{
    BSTNode *p1,*p2;
    if (p->bf==0)           //原本左、右子树等高,现因右子树增高而使树增高
    {
        p->bf=-1;
        taller=1;
    }
    else if (p->bf==1)      //原本左子树比右子树高,现左、右子树等高
    {
        p->bf=0;
        taller=0;
    }
    else                    //原本右子树比左子树高,需作右子树的平衡处理
    {
        p1=p->rchild;       //p指向*p的右子树根结点
        if (p1->bf==-1)     //新结点插入在*b的右孩子的右子树上,要作RR调整
        {
            p->rchild=p1->lchild;
            p1->lchild=p;
            p->bf=p1->bf=0;
            p=p1;
        }
        else if (p1->bf==1) //新结点插入在*p的右孩子的左子树上,要作RL调整
        {
            p2=p1->lchild;
            p1->lchild=p2->rchild;
            p2->rchild=p1;
            p->rchild=p2->lchild;
            p2->lchild=p;
            if (p2->bf==0)          //新结点插在*p2处作为叶子结点的情况
                p->bf=p1->bf=0;
            else if (p2->bf==-1)    //新结点插在*p2的右子树上的情况
            {
                p1->bf=0;
                p->bf=1;
            }
            else                    //新结点插在*p2的左子树上的情况
            {
                p1->bf=-1;
                p->bf=0;
            }
            p=p2;
            p->bf=0;            //仍将p指向新的根结点,并置其bf值为0
        }
        taller=0;
    }
}
int InsertAVL(BSTNode *&b,KeyType e,int &taller)
/*若在平衡的二叉排序树b中不存在和e有相同关键字的结点,则插入一个
  数据元素为e的新结点,并返回1,否则返回0。若因插入而使二叉排序树
  失去平衡,则作平衡旋转处理,布尔变量taller反映b长高与否*/
{
    if(b==NULL)         //原为空树,插入新结点,树“长高”,置taller为1
    {
        b=(BSTNode *)malloc(sizeof(BSTNode));
        b->key=e;
        b->lchild=b->rchild=NULL;
        b->bf=0;
        taller=1;
    }
    else
    {
        if (e==b->key)              //树中已存在和e有相同关键字的结点则不再插入
        {
            taller=0;
            return 0;
        }
        if (e<b->key)               //应继续在*b的左子树中进行搜索
        {
            if ((InsertAVL(b->lchild,e,taller))==0) //未插入
                return 0;
            if (taller==1)          //已插入到*b的左子树中且左子树“长高”
                LeftProcess(b,taller);
        }
        else                        //应继续在*b的右子树中进行搜索
        {
            if ((InsertAVL(b->rchild,e,taller))==0) //未插入
                return 0;
            if (taller==1)          //已插入到b的右子树且右子树“长高”
                RightProcess(b,taller);
        }
    }
    return 1;
}
void DispBSTree(BSTNode *b) //以括号表示法输出AVL
{
    if (b!=NULL)
    {
        printf("%d",b->key);
        if (b->lchild!=NULL || b->rchild!=NULL)
        {
            printf("(");
            DispBSTree(b->lchild);
            if (b->rchild!=NULL) printf(",");
            DispBSTree(b->rchild);
            printf(")");
        }
    }
}
void LeftProcess1(BSTNode *&p,int &taller)  //在删除结点时进行左处理
{
    BSTNode *p1,*p2;
    if (p->bf==1)
    {
        p->bf=0;
        taller=1;
    }
    else if (p->bf==0)
    {
        p->bf=-1;
        taller=0;
    }
    else        //p->bf=-1
    {
        p1=p->rchild;
        if (p1->bf==0)          //需作RR调整
        {
            p->rchild=p1->lchild;
            p1->lchild=p;
            p1->bf=1;
            p->bf=-1;
            p=p1;
            taller=0;
        }
        else if (p1->bf==-1)    //需作RR调整
        {
            p->rchild=p1->lchild;
            p1->lchild=p;
            p->bf=p1->bf=0;
            p=p1;
            taller=1;
        }
        else                    //需作RL调整
        {
            p2=p1->lchild;
            p1->lchild=p2->rchild;
            p2->rchild=p1;
            p->rchild=p2->lchild;
            p2->lchild=p;
            if (p2->bf==0)
            {
                p->bf=0;
                p1->bf=0;
            }
            else if (p2->bf==-1)
            {
                p->bf=1;
                p1->bf=0;
            }
            else
            {
                p->bf=0;
                p1->bf=-1;
            }
            p2->bf=0;
            p=p2;
            taller=1;
        }
    }
}
void RightProcess1(BSTNode *&p,int &taller) //在删除结点时进行右处理
{
    BSTNode *p1,*p2;
    if (p->bf==-1)
    {
        p->bf=0;
        taller=-1;
    }
    else if (p->bf==0)
    {
        p->bf=1;
        taller=0;
    }
    else        //p->bf=1
    {
        p1=p->lchild;
        if (p1->bf==0)          //需作LL调整
        {
            p->lchild=p1->rchild;
            p1->rchild=p;
            p1->bf=-1;
            p->bf=1;
            p=p1;
            taller=0;
        }
        else if (p1->bf==1)     //需作LL调整
        {
            p->lchild=p1->rchild;
            p1->rchild=p;
            p->bf=p1->bf=0;
            p=p1;
            taller=1;
        }
        else                    //需作LR调整
        {
            p2=p1->rchild;
            p1->rchild=p2->lchild;
            p2->lchild=p1;
            p->lchild=p2->rchild;
            p2->rchild=p;
            if (p2->bf==0)
            {
                p->bf=0;
                p1->bf=0;
            }
            else if (p2->bf==1)
            {
                p->bf=-1;
                p1->bf=0;
            }
            else
            {
                p->bf=0;
                p1->bf=1;
            }
            p2->bf=0;
            p=p2;
            taller=1;
        }
    }
}
void Delete2(BSTNode *q,BSTNode *&r,int &taller)
//由DeleteAVL()调用,用于处理被删结点左右子树均不空的情况
{
    if (r->rchild==NULL)
    {
        q->key=r->key;
        q=r;
        r=r->lchild;
        free(q);
        taller=1;
    }
    else
    {
        Delete2(q,r->rchild,taller);
        if (taller==1)
            RightProcess1(r,taller);
    }
}
int DeleteAVL(BSTNode *&p,KeyType x,int &taller) //在AVL树p中删除关键字为x的结点
{
    int k;
    BSTNode *q;
    if (p==NULL)
        return 0;
    else if (x<p->key)
    {
        k=DeleteAVL(p->lchild,x,taller);
        if (taller==1)
            LeftProcess1(p,taller);
        return k;
    }
    else if (x>p->key)
    {
        k=DeleteAVL(p->rchild,x,taller);
        if (taller==1)
            RightProcess1(p,taller);
        return k;
    }
    else            //找到了关键字为x的结点,由p指向它
    {
        q=p;
        if (p->rchild==NULL)        //被删结点右子树为空
        {
            p=p->lchild;
            free(q);
            taller=1;
        }
        else if (p->lchild==NULL)   //被删结点左子树为空
        {
            p=p->rchild;
            free(q);
            taller=1;
        }
        else                        //被删结点左右子树均不空
        {
            Delete2(q,q->lchild,taller);
            if (taller==1)
                LeftProcess1(q,taller);
            p=q;
        }
        return 1;
    }
}
int main()
{
    BSTNode *b=NULL;
    int i,j,k;
    KeyType a[]= {16,3,7,11,9,26,18,14,15},n=9; //例10.5
    printf(" 创建一棵AVL树:\n");
    for(i=0; i<n; i++)
    {
        printf("   第%d步,插入%d元素:",i+1,a[i]);
        InsertAVL(b,a[i],j);
        DispBSTree(b);
        printf("\n");
    }
    printf("   AVL:");
    DispBSTree(b);
    printf("\n");
    printf(" 删除结点:\n");                     //例10.6
    k=11;
    printf("   删除结点%d:",k);
    DeleteAVL(b,k,j);
    printf("   AVL:");
    DispBSTree(b);
    printf("\n");
    k=9;
    printf("   删除结点%d:",k);
    DeleteAVL(b,k,j);
    printf("   AVL:");
    DispBSTree(b);
    printf("\n");
    k=15;
    printf("   删除结点%d:",k);
    DeleteAVL(b,k,j);
    printf("   AVL:");
    DispBSTree(b);
    printf("\n\n");
    return 0;
}

运行结果截图如下:

2018122814580746.png


相关文章
|
5月前
|
存储 算法 生物认证
基于Zhang-Suen算法的图像细化处理FPGA实现,包含testbench和matlab验证程序
本项目基于Zhang-Suen算法实现图像细化处理,支持FPGA与MATLAB双平台验证。通过对比,FPGA细化效果与MATLAB一致,可有效减少图像数据量,便于后续识别与矢量化处理。算法适用于字符识别、指纹识别等领域,配套完整仿真代码及操作说明。
机器学习/深度学习 算法 自动驾驶
1034 0
|
5月前
|
算法 API 数据安全/隐私保护
深度解析京东图片搜索API:从图像识别到商品匹配的算法实践
京东图片搜索API基于图像识别技术,支持通过上传图片或图片URL搜索相似商品,提供智能匹配、结果筛选、分页查询等功能。适用于比价、竞品分析、推荐系统等场景。支持Python等开发语言,提供详细请求示例与文档。
|
7月前
|
存储 监控 安全
企业上网监控系统中红黑树数据结构的 Python 算法实现与应用研究
企业上网监控系统需高效处理海量数据,传统数据结构存在性能瓶颈。红黑树通过自平衡机制,确保查找、插入、删除操作的时间复杂度稳定在 O(log n),适用于网络记录存储、设备信息维护及安全事件排序等场景。本文分析红黑树的理论基础、应用场景及 Python 实现,并探讨其在企业监控系统中的实践价值,提升系统性能与稳定性。
289 1
|
7月前
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
201 0
|
7月前
|
存储 算法 数据安全/隐私保护
基于FPGA的图像退化算法verilog实现,分别实现横向和纵向运动模糊,包括tb和MATLAB辅助验证
本项目基于FPGA实现图像运动模糊算法,包含横向与纵向模糊处理流程。使用Vivado 2019.2与MATLAB 2022A,通过一维卷积模拟点扩散函数,完成图像退化处理,并可在MATLAB中预览效果。
|
8月前
|
监控 算法 安全
公司电脑监控软件关键技术探析:C# 环形缓冲区算法的理论与实践
环形缓冲区(Ring Buffer)是企业信息安全管理中电脑监控系统设计的核心数据结构,适用于高并发、高速率与短时有效的多源异构数据处理场景。其通过固定大小的连续内存空间实现闭环存储,具备内存优化、操作高效、数据时效管理和并发支持等优势。文章以C#语言为例,展示了线程安全的环形缓冲区实现,并结合URL访问记录监控应用场景,分析了其在流量削峰、关键数据保护和高性能处理中的适配性。该结构在日志捕获和事件缓冲中表现出色,对提升监控系统效能具有重要价值。
223 1
|
9月前
|
监控 算法 数据处理
基于 C++ 的 KD 树算法在监控局域网屏幕中的理论剖析与工程实践研究
本文探讨了KD树在局域网屏幕监控中的应用,通过C++实现其构建与查询功能,显著提升多维数据处理效率。KD树作为一种二叉空间划分结构,适用于屏幕图像特征匹配、异常画面检测及数据压缩传输优化等场景。相比传统方法,基于KD树的方案检索效率提升2-3个数量级,但高维数据退化和动态更新等问题仍需进一步研究。未来可通过融合其他数据结构、引入深度学习及开发增量式更新算法等方式优化性能。
228 17
|
9月前
|
存储 算法 安全
如何控制上网行为——基于 C# 实现布隆过滤器算法的上网行为管控策略研究与实践解析
在数字化办公生态系统中,企业对员工网络行为的精细化管理已成为保障网络安全、提升组织效能的核心命题。如何在有效防范恶意网站访问、数据泄露风险的同时,避免过度管控对正常业务运作的负面影响,构成了企业网络安全领域的重要研究方向。在此背景下,数据结构与算法作为底层技术支撑,其重要性愈发凸显。本文将以布隆过滤器算法为研究对象,基于 C# 编程语言开展理论分析与工程实践,系统探讨该算法在企业上网行为管理中的应用范式。
261 8
|
9月前
|
存储 监控 算法
基于 C# 时间轮算法的控制局域网上网时间与实践应用
在数字化办公与教育环境中,局域网作为内部网络通信的核心基础设施,其精细化管理水平直接影响网络资源的合理配置与使用效能。对局域网用户上网时间的有效管控,已成为企业、教育机构等组织的重要管理需求。这一需求不仅旨在提升员工工作效率、规范学生网络使用行为,更是优化网络带宽资源分配的关键举措。时间轮算法作为一种经典的定时任务管理机制,在局域网用户上网时间管控场景中展现出显著的技术优势。本文将系统阐述时间轮算法的核心原理,并基于 C# 编程语言提供具体实现方案,以期深入剖析该算法在局域网管理中的应用逻辑与实践价值。
232 5

热门文章

最新文章