数据结构实验—基于二叉排序树的商品信息查询算法的设计与实现

【问题描述】
查找表是数据处理的重要操作, 试建立有100个结点的二叉排序树进行查找,然后用原数据建立AVL树, 并比较两者的平均查找长度。
【基本要求】
(1)以链表作为存储结构,实现二叉排序树的建立、查找和删除。
(2)根据给定的数据建立平衡二叉树。
(3)比较二叉排序树和平衡二叉树的平均查找长度。
【测试数据】
随机生成。
【实现提示】
(1)初始,二叉排序树和平衡二叉树都为空树,操作界面给出查找、插入和删除三种操作供选择。每种操作均要提示输入关键字。每次插入或删除一个结点后,应更新平衡二叉树或二叉排序树的显示。
(2)平衡二叉树或二叉排序树的显示可以采用凹入表形式,也可以采用图形界面画出树形。

树的结构体类型定义:

struct node{
   
    int data;//数据项
    int degree;//平衡二叉树的平衡因子
    node *lchild;
    node *rchild;//左右孩子
    node *parent;
    int length;
};

这里定义了父母指针,主要用途在于删除结点时使用。还有查找长度。
首先说明生成二叉排序树的思路:
以插入为基础算法,不断地插入新的结点,从而构造一棵二叉排序树。
AVL树(平衡二叉树)的基本思路相同,但需要不断地做平衡处理。
二叉排序树的递归插入:

node *binary_sort_tree(node* &T,int a){
   //产生普通二叉排序树,即插入操作
    if(T== NULL){
   
        T=new node;
        T->data=a;
        T->lchild=NULL;
        T->rchild=NULL;
        T->parent=NULL;
    }
    else if(a < T->data){
   
        T->lchild=binary_sort_tree(T->lchild,a);
        T->lchild->parent=T;
    }
    else if(a> T->data){
   
        T->rchild=binary_sort_tree(T->rchild,a);
        T->rchild->parent=T;
    }
    else
        cout<<"该结点已存在,请勿重复插入"<<endl;
    return T;
}

AVL树的难点在于平衡思路,可以分为两大类,四小类:
L型:因左子树插入结点而引起的失衡
LL型——>单次右旋转一次。
LR型——>首先左旋转左子树一次,再右旋转大树一次。
R型:因右子树插入结点而引起的失衡
RR型——>单次左旋转一次。
RL型——>首先右旋转右子树一次,再左旋转大树一次。
主要的插入函数负责两大类:L与R型的平衡。而其名下的两小类,则分别由LeftBalance与RightBalance函数处理平衡。
这里由最底层的函数开始给出:
单次左旋转函数:

void L_Rotate(node* &T){
   //对树作左旋处理
    node* rc=T->rchild;
    T->rchild=rc->lchild;
    rc->lchild=T;
    T=rc;
}

单次右旋转函数:

void R_Rotate(node* &T){
   //对树作右旋处理
    node* lc=T->lchild;
    T->lchild=lc->rchild;
    lc->rchild=T;
    T=lc;
}

左平衡函数:

void LeftBalance(node* &T){
   
    node *lc=T->lchild;
    switch(lc->degree){
   
    case 1:
        T->degree=0;
        lc->degree=0;
        R_Rotate(T);
        break;
    case -1:
        node *rd=lc->rchild;
        switch(rd->degree){
   
        case 1:
            T->degree=-1;
            lc->degree=0;
            break;
        case 0:
            T->degree=0;
            lc->degree=0;
            break;
        case -1:
            T->degree=0;
            lc->degree=1;
            break;
        }
        rd->degree=0;
        L_Rotate(T->lchild);
        R_Rotate(T);
    }
}

右平衡函数:

void RightBalance(node* &T){
   
    node *rc=T->rchild;
    switch(rc->degree){
   
    case -1:
        T->degree=0;
        rc->degree=0;
        L_Rotate(T);
        break;
    case 1:
        node *ld=rc->lchild;
        switch(ld->degree){
   
        case 1:
            T->degree=0;
            rc->degree=-1;
            break;
        case 0:
            T->degree=0;
            rc->degree=0;
            break;
        case -1:
            T->degree=1;
            rc->degree=0;
        }
        ld->degree=0;
        R_Rotate(T->rchild);//单次右旋转右子树
        L_Rotate(T);//单次左旋转树
    }
}

最后是最关键的插入操作函数:

int InsertAVL(node* &T,int a,int &flag){
   //构造平衡二叉树
    if(!T){
   
        T=new node;
        T->data=a;
        T->lchild=NULL;
        T->rchild=NULL;
        T->degree=0;//平衡因子
        flag=1;//反映树长高与否
    }
    else{
   
        int length;
        if(search_tree(T,a,length)){
   
            flag=0;
            return 0;
        }
        if(T->data>a){
   
            if(!InsertAVL(T->lchild,a,flag))
                return 0;
            if(flag)
            switch(T->degree){
   
            case 1:
                LeftBalance(T);
                flag=0;
                break;
            case 0:
                T->degree=1;
                flag=1;
                break;
            case -1:
                T->degree=0;
                flag=0;
                break;
            }
        }
        else{
   
            if(!InsertAVL(T->rchild,a,flag))
                return 0;
            if(flag)
            switch(T->degree
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值