查找算法:二叉平衡树、散列表、二分查找、顺序查找、分块查找

二叉排序树

//
// Created by lijing on 23-12-7.
//
#include "../../Define.h"
#define ENDFLAG -1
typedef int KeyType;
typedef int InfoType;
//- - - - -二叉排序树的二叉链表存储表示- - - - -
typedef struct
{
    KeyType key;                                 //关键字项
    InfoType otherinfo;                          //其他数据项
}ElemType;                                      //每个结点的数据域的类型
typedef struct BSTNode
{
    ElemType data;                               //每个结点的数据域包括关键字项和其他数据项
    struct BSTNode *lchild,*rchild;              //左右孩子指针
}BSTNode,*BSTree;
void PritBST(BSTree T){
    if(T){
        PritBST(T->lchild);
        cout<<T->data.key<<" ";
        PritBST(T->rchild);
    }
}
//二叉排序树
//- - - - -二叉排序树的查找- - - - -
/*二叉排序树可以看成是一个有序表,所以在二叉排序树上进行查找和折半查找类似,也是一个逐步缩小查找范围的过程。*/
BSTree SearchBST(BSTree T,KeyType key)
{   //在根指针T所指二叉排序树中递归地查找某关键字等于key的数据元素
    //若查找成功,则返回指向该数据元素结点的指针,否则返回空指针
    if((!T)||key==T->data.key) return T;                      //查找结束
    else if(key < T->data.key) return SearchBST(T->lchild,key); //在左子树中继续查找
    else return SearchBST(T->rchild,key);                     //在右子树中继续查找
}
//- - - - -二叉排序树的插入- - - - -
/**/
void InsertBST(BSTree &T, ElemType e)
{//当二叉排序树T中不存在关键字等于e.key的数据元素时,则插入该元素
    if(!T)
    {                              //找到插入位置,递归结束
        BSTNode* S=new BSTNode;              //生成新结点*S
        S->data=e;                  //新结点*S的数据域置为e
        S->lchild=S->rchild=NULL;   //新结点*S作为叶子结点
        T=S;                        //把新结点*S链接到已找到的插入位置
    }
    else if(e.key<T->data.key)
        InsertBST(T->lchild, e );  //将*S插入左子树
    else if (e.key> T->data.key)
        InsertBST(T->rchild, e);   //将*S插入右子树
}
//- - - - -二叉排序树的创建- - - - -
/*【算法步骤】
 * ① 将二叉排序树T初始化为空树。
 * ② 读入一个关键字为key的结点。
 * ③ 如果读入的关键字key不是输入结束标志,则循环执行以下操作:
 *  ·将此结点插入二叉排序树T中;
 *  ·读入一个关键字为key的结点。*/
void CreatBST(BSTree &T)
{//依次读入一个关键字为key的结点,将此结点插入二叉排序树T中
    T=NULL;                  //将二叉排序树T初始化为空树
    ElemType e;
    cout<<"请输入关键字为key的结点,以-1结束:"<<endl;
    cin>>e.key;
    while(e.key!=ENDFLAG)    //ENDFLAG为自定义常量,作为输入结束标志
    {
        InsertBST(T,e);       //将此结点插入二叉排序树T中
        cin>>e.key;
    }
    cout<<"二叉排序树创建完成"<<endl;

}
//- - - - -二叉排序树的删除- - - - -

int main(){
    BSTree T;
    CreatBST(T);
    PritBST(T);
}
/home/lijing/CLionProjects/DataStructureAlgorithms2/BinarySearchTree
请输入关键字为key的结点,以-1结束:
6 9 23 12 11 45 23 -1
二叉排序树创建完成
6 9 11 12 23 45 
Process finished with exit code 0

散列表

//
// Created by lijing on 23-12-7.
//
//- - - - -开放地址法散列表的存储表示- - - - -
#define m 20   //散列表的表长
#define MOD 13
typedef int KeyType;               //关键字类型
typedef int InfoType;              //其他数据项类型
typedef struct{
    KeyType key;                    //关键字项
    InfoType otherinfo;             //其他数据项
}HashTable[m];
#define NULLKEY 0                               //单元为空的标记
int H(KeyType key){
    return key % MOD;                            //散列函数
}
//- - - - -线性探测法散列函数- - - - -
int SearchHash(HashTable HT,KeyType key)
{//在散列表HT中查找关键字为key的元素,若查找成功,返回散列表的单元标号,否则返回-1
    int i,H0,Hi;
    H0=H(key);                                  //根据散列函数H(key)计算散列地址
    if(HT[H0].key==NULLKEY) return -1;          //若单元H0为空,则所查元素不存在
    else if(HT[H0].key==key) return H0;         //若单元H0中元素的关键字为key,则查找成功
    else
    {
        for(i=1;i<m;++i)
        {
            Hi=(H0+i)%MOD;                          //按照线性探测法计算下一个散列地址Hi
            if(HT[Hi].key==NULLKEY) return -1;    //若单元Hi为空,则所查元素不存在
            else if(HT[Hi].key==key) return Hi;   //若单元Hi中元素的关键字为key,则查找成功
        }                                        //for
        return -1;
    }                                          //else
}

线性表:顺序查找 二分查找 分块查找

//Sequential Search
// Created by lijing on 23-11-27.
#include "../../Define.h"
typedef int KeyType;
typedef int InfoType;
typedef struct{
    KeyType key;                                        //关键字域
    InfoType otherinfo;                                 //其他域
}ElemType;
typedef struct{
    ElemType *R;                                        //存储空间基地址
    int length;                                         //当前长度
}SSTable;
//--------------------------顺序查找--------------------------------------
//假设元素从ST.R[1]开始顺序向后存放,ST.R[0]闲置不用,查找时从表的最后开始比较
//顺序查找的平均时间复杂度为O(n),当n很大时,效率很低
//优点:实现简单,适用线性表的顺序存储结构,又适用于线性表的链式存储结构,
int Search_Seq(SSTable ST,KeyType key)
{    //在顺序表ST中顺序查找其关键字等于key的数据元素。
     // 若找到,则函数值为该元素在表中的位置,否则为0
//    for(int i=ST.length;i>=1;--i)
//        if(ST.R[i].key==key) return i;//从后往前找,使用哨兵免去检测是否满足i》=1
//    return 0;
    ST.R[0].key=key; //“哨兵”
    // 这个改进能使顺序查找在ST.length≥1000时,进行一次查找所需的平均时间几乎减少一半
    for (int i = ST.length ; ST.R[i].key !=key ; ++i) {
        return i;
    }
}

//--------------------------折半查找/二分查找--------------------------------------
/*
折半查找(必须采用顺序查找,且表中元素按关键字有序排列),每查找一次,查找区间缩小一半。
 不适用于数据元素经常变动的线性表
 【算法步骤】
① 置查找区间初值,low为1,high为表长。
② 当low小于等于high时,循环执行以下操作:
    ·mid取值为low和high的中间值;
    ·将给定值key与中间位置记录的关键字进行比较,若相等则查找成功,返回中间位置mid;
    ·若不相等则利用中间位置记录将表对分成前、后两个子表。
     如果key比中间位置记录的关键字小,则high取为mid-1,否则low取为mid+1。
 ③ 循环结束,说明查找区间为空,则查找失败,返回0。*/
int Search_Bin(SSTable ST,KeyType key)
{//在有序表ST中折半查找其关键字等于key的数据元素。若找到,则函数值为该元素在表中的位置,否则为0
    int low=1;
    int high=ST.length;                       //置查找区间初值
    int mid;
    while(low<=high)
    {/*循环执行的条件是low<=high,而不是low<high,
        因为low=high时,查找区间还有最后一个结点,还要进一步比较。*/
        mid=(low+high)/2;
        if(key==ST.R[mid].key) return mid;       //找到待查元素
        else if(key<ST.R[mid].key) high=mid-1;   //继续在前一子表进行查找
        else low=mid+1;                          //继续在后一子表进行查找
    }                                           //while
    return 0;                                   //表中不存在待查元素
}
//递归实现

//--------------------------分块查找--------------------------------------





  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值