7.2 数据结构——查找(线性表)

7.2.1 顺序查找

1、应用范围:

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

2、数据元素类型定义:

typedef struct
{
    KeyType key;  //关键字域
    ...;          //其它域
}ElemType;

typedef struct
{
    ElemType R[MAXSIZE];
    int length;
}SSTable;

3、在顺序表ST中查找值为key的数据元素,例如:

int Search_Seq(SSTable ST, KeyType key)
{
    for (int i = ST.length; ST.R[i].key != key && i > 0; --i);

    if (i > 0)
        return i;
    else
        return 0;
}

 这种方法没执行一次循环都要进行两次比较。

4、改进:把待查找关键字key存放入表头(“哨兵”,“监视哨”),从后往前逐个比较,可免去查找过程中每一步都要检测是否查找完毕,加快速度。

int Search_Seq(SSTable ST, KeyType key)
{
    ST.R[0].key = key;
    for (int i = ST.length; ST.R[i].key != key; --i);

    return i;
}

5、时间效率分析:

比较次数与位置有关:查找第i个元素,需比较n-i+1次;查找失败,需比较n+1次。

6、顺序查找的性能分析:

时间复杂度:O(n)

查找成功的平均查找长度,设表中各记录查找概率相等;ASLs(n) = (1+2+...+n)/n = n+1/2

空间复杂度:一个辅助空间O(1)

7、记录的查找概率不相等时如何提高查找效率?

查找表存储记录原则——按查找概率高低存储

(1)查找概率越高,比较次数越少

(2)查找概率月底,比较次数越多

8、记录的查找概率无法测定时如何提高查找效率?

方法:按查找概率动态调整记录顺序

(1)在每一个记录中设一个访问频度域

(2)始终保持记录按非递增有序的次序排序

(3)每次查找后均将刚查到的记录一道表头

9、顺序查找的特点:

优点:算法简单,逻辑次序无要求,且不同存储结构均适用

缺点:ASL太长,时间效率太低

7.2.2 折半查找(二分查找或对分查找)

1、折半查找:每次将待查找记录所在区间缩小一半。

2、查找过程:

3、折半查找算法(非递归算法):

设表长为n,low、high和mid分别指向待查找元素所在区间的上界、下届和中点,key为给定的要查找的值。

(1)初始时令low = 1,high = n,mid = \left \lfloor (low+high)/2 \right \rfloor

(2)让key 与mid指向的记录比较:

        若key = ST.R[mid].key,则查找成功;

        若key < ST.R[mid].key,则high = mid - 1;

        若key > ST.R[mid].key,则low = mid + 1.

(3)重复上述操作,直至low > high时,折半查找失败。

折半查找的非递归算法实现:

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

 折半查找的递归算法实现:

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

4、折半查找的性能分析——判定树

 

比较次数 = 路径上的结点数 = 结点的层数

比较次数 <= 树的深度 <= \left \lfloor log_{2}n \right \rfloor + 1

假设每个元素的查找概率相等,求查找成功时的平均查找长度:

ASL = (1*1 + 2*2 + 4*3 +4*4) / 11= 3 

5、折半查找的特点:

优点:效率比顺序查找高

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

7.2.3 分块查找(索引顺序查找)

1、步骤:

(1)将表分成几块,且表或者有序,或者分块有序;若 i < j,则第 j 块中所有记录的关键字均大于第 i 块的最大关键字。

(2)建立“索引表”(每个结点含有最大关键字域和指向本块第一个结点的指针,且关键字有序)。

2、查找过程:先确定待查记录所在块(顺序或折半查找),再在块内查找(顺序查找)。

3、分块查找的优缺点

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

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

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

7.2.4 三种查找的比较

顺序查找折半查找分块查找
ASL最大最小中间
表结构有序、无序有序分块有序
存储结构顺序表、线性链表顺序表顺序表、线性链表

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值