第七章查找

导读:本篇文章讲解 第七章查找,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

目录

 

基本概念

线性表的查找

顺序查找(线性查找)

顺序查找算法        O(n)

设置监视哨的顺序查找        O(n)

顺序查找的优缺点

折半查找(二分查找)        O(log2n)

折半查找的算法

折半查找的递归算法

折半查找的判定树

折半查找的优缺点

分块查找

 查找方法比较

树表的查找

二叉排序树

二叉排序树的存储结构

二叉排序树的查找操作        O(log2n)

二叉排序树的插入操作        O(log2n)

二叉排序树的创建操作        O(nlog2n)

二叉排序树的删除操作

平衡二叉树        AVL树

失衡二叉排序树的调整原则

散列表的查找

直接定址法

除留余数法

 处理冲突的方法

开放地址法

线性探测法 

 链地址法

优点

基本概念

根据给定的一个值,在查找表中确定一个关键字等于给定值的数据元素或(记录)

关键字:用来标识一个数据元素(或记录)的某个数据项的值

主关键字:可唯一地标识一个记录的关键字是主关键字

次关键字:用以标识若干记录的关键字是次关键字

线性表的查找

顺序查找(线性查找)

应用范围

  • 顺序表或线性链表表示的静态查找表
  • 表内元素之间无序

顺序表的数据元素类型定义

typedef struct{
    KeyType key;    //关键字域
    ……              //其他域
}ElemType;

顺序表的表示

typedef struct{    //顺序表结构类型定义
    ElemType *R;    //基地址
    int length;     //表长
}SSTable;
SSTable ST;  //定义顺序表ST

顺序查找算法        O(n)

int Search_Seq(SSTable ST,KeyType key){
    //若成功返回其位置信息,否则返回0
    for(i=ST.length;i>=1;--i)
        if(ST.R[i].key == key)    return i;    
    return 0;
}

设置监视哨的顺序查找        O(n)

int Search_Seq(SSTable ST,KeyType key){
    //在顺序表ST中顺序查找其关键字等于key的数据元素
    ST.R[0].key=key;        //"哨兵"
    for(i=ST.length;ST.R[i].key!=key;--i);
    return i;
}

查找第i个元素,需要比较n-i+1次;查找失败,需比较n+1次。

平均查找长度(n+1)/2

空间复杂度为O(1)

第七章查找

顺序查找的优缺点

优点:算法简单,对表结构无任何要求,既适用于顺序结构,也适用于链式结构,无论记录是否按关键字有序均可应用。

缺点:平均查找长度较大,查找效率较低,所以当n很大时,不宜采用顺序查找

折半查找(二分查找)        O(log2n)

mid = (low + high)/2

折半查找的算法

int Search_Bin(SSTable ST,KeyType key){
    low = 1;high = ST.length;    //置区间初值
    while(low <= high){
        mid = (low+high)/2;
        if(ST.R[mid].key == key)    return mid;
        else if(key < ST.R[mid].key)
            high = mid-1;
        else low = mid+1;
    }
    return 0;
}

折半查找的递归算法

int Search_Bin(SSTable ST,keyType key, int low,int high){
    if(low > high)    return 0;
    mid = (low + high)/2;
    if(key == ST.elem[mid].key)    return mid;
    else if(key < ST.elem[mid].key)
        Search_Bin(SSTable ST,keyType key, int low,int mid-1);
    else    
        Search_Bin(SSTable ST,keyType key, int mid+1,int high);
}

折半查找的判定树

第七章查找

时间复杂度为O(log2n)

平均查找长度ASL=log2(n+1)-1

折半查找的优缺点

优点:效率比顺序查找高

缺点:只适用于有序表,且限于顺序存储结构(对线性链表无效)

分块查找

第七章查找

第七章查找

优点:插入和删除比较容易,无需进行大量移动

缺点:要增加一个索引表的存储空间并对初始索引表进行排序运算

适用情况:如果线性表既要快速查找又经常动态变化,则可采用分块查找

 查找方法比较

第七章查找

树表的查找

动态查找表–对于给定值key,若表中存在,则成功返回;否则,插入关键字等于key的记录

二叉排序树

二叉排序树或是空树,或是满足以下性质的二叉树

  • 若其左子树非空,则左子树上所有结点的值均小于根结点的值
  • 若其右子树非空,则右子树上所有结点的值均大于等于根结点的值
  • 其左右子树本身又是一棵二叉排序树

中序遍历非空的二叉排序树是一个按关键字排列的递增有序的序列

比较的关键字次数=此结点所在层次数

最多的比较次数=树的深度 

二叉排序树的存储结构

typedef struct{
    KeyType key;    //关键字项
    InfoType otherinfo;    //其他数据域
}ElemType;

typedef struct BSTNode{
    ElemType data;        //数据域
    struct BSTNode *lchild,*rchild;    //左右孩子指针
}BSTNode,*BSTree;

BSTree T;    //定义二叉排序树T

二叉排序树的查找操作        O(log2n)

BSTree SearchBST(BSTree T,KeyType 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);    //在右子树中继续查找
}

含有n个结点的平均查找长度最好情况:O(log2n)

最坏情况:O(n)

二叉排序树的插入操作        O(log2n)

插入的元素一定在叶结点上

void InsertBST(BSTree &T,ElemType e){
    //当二叉排序树T中不存在关键字等于e.key的数据元素时,则插入该元素
    if(!T){
        S = new BSTNode;                    //生成新结点*S
        S -> data = e;
        S -> lchild = S -> rchild = NULL;    //新结点*S作为叶子结点
        T = S;
    }
    else if(e.key < T -> data.key)
        InsertBST(T -> lchild,key);
    else if(e.key < T -> data.key)
        InsertBST(T -> lchild,key);
}

二叉排序树的创建操作        O(nlog2n)

不同插入次序的序列生成不同形态的二叉排序树

void CreateBST(BSTree &T){
    //依次读入一个关键字为key的结点,将结点插入二叉排序树T中
    T = NULL;
    cin >> e;
    while(e.key != ENDFLAG){    //ENDFLAG为自定义常量,作为输入结束标志
        Insert(T,e);
        cin >> e;
    }
}

二叉排序树的删除操作

①被删除的结点是叶子结点:直接删去该结点

②被删除的结点只有左子树或者只有右子树,用其左子树或者右子树替换它(结点替换)

③若被删除的结点既有左子树,又有右子树,则用其中序前驱结点的值代替它(前驱是左子树中最大的结点),然后再删除该前驱结点;也可以用其后继替换之,然后再删除该后继结点,后继是右子树中最小的结点

平衡二叉树        AVL树

①左子树和右子树的深度之差的绝对值不超过1

②左子树和右子树也是平衡二叉排序树

若将二叉树上结点的平衡因子(BF)定义为该结点左子树和右子树的深度之差,则平衡二叉树上所有结点的平衡因子只可能是-1,1,0

对于一个有n个结点的AVL树,其高度保持在O(log2n)数量级,ASL也保持在O(log2n)量级

失衡二叉排序树的调整原则

①降低高度

②保持二叉排序树性质

散列表的查找

直接定址法

Hash(key) = a*key + b (a,b为常数)

优点:以关键码key的某个线性函数值为散列地址,不会产生冲突

缺点:要占用连续的地址空间,空间效率低

除留余数法

Hash(key) = key mod p  (p是一个整数,且是一个质数  p <= 表长m)

 处理冲突的方法

开放地址法

基本思想:有冲突时就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将数据元素存入

第七章查找

线性探测法 

一旦冲突,就找下一个地址,直到找到空地址存入

第七章查找

第七章查找

第七章查找

 链地址法

第七章查找

 0-12(13种可能,所以需要mod13)

优点

①非同义词不会冲突,无“聚集”现象

②链表上结点空间动态申请,更适合于表长不确定的情况

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/83248.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!