查找:线性表的查找

1.什么是查找:
查找是给定的某个值key在表中确定是否有一个关键字的值等于给定值key的记录或数据元素。

2.查找算法的分类:
动态查找:在查找的同时对表记录做修改(如插入、删除)。
静态查找:在查找的同时不对表进行任何改动。

注:如果查找的全过程都在内存中进行,称为内查找
如果查找的全过程需要访问外存,称为外查找

3.查找算法性能比较的评估指标:
平均查找长度(Average Search length,ASL)
由于查找算法的运算是关键字的比较过程,所以通常把查找过程中对关键字需要执行的平均比较次数(或者称为平均比较长度)作为衡量一个查找算法效率的比较标准。

4.选取查找算法的因素:
1)使用什么数据存储结构(例如线性表,树形表)
2)表中的次序,即对有序表还是无序表进行查找

一:顺序查找(无序表查找)

要点:顺序查找是一种最简单的查找算法,效率很低下。

存储结构:没有存储结构要求,可以无序,也可以有序。

基本思想:从数据结构线性表的一端开始顺序扫描,依次将扫描到的结点关键字与给定值key进行比较,若相等则表示查找成功;
若扫描结束扔没有找到关键字等于给定值key的结点,则表示查找失败

python3代码实现

# -*- coding: utf-8 -*-
"""
Created on Fri Jul 12 18:44:33 2019

@author: ZQQ
"""

def orderSearch(input_list, key):
    print('待查找的列表:',input_list)
    print('要查找的关键字:', key)
    length = len(input_list) # 计算列表长度
    print('待查找的列长度:',length)
    
    # 情况1:序列为空,查找失败
    if length == 0:
        print('查找失败')
        return False
    # 情况2:序列不为空
    else:
        for i in range(length):
            if input_list[i] == key:
                print('查找成功,在待查找列表的位置为:%d' % i)
                return i # 条件成立,查找成功,返回表中的索引,
        else:
            print('查找失败')
            return False
                            
#if __name__ == '__main__':
#input_list = []
input_list = [1,3,5,15,7,9,13,15,15]
result = orderSearch(input_list, 15)
print(result)

运行结果:
在这里插入图片描述
可以看出待查找的列表中有3个15,程序运行只返回第一个15的位置。

算法分析:
顺序查找算法最好的情况是,待查找的列表中第一个关键字就是要查找的数值,则需要比较1次
最坏的情况:最后一个关键字是要查找的数值,则需要比较n次
所以顺序查找算法的平均查找长度为:
ASL = (1+2+…+n-1+n)/ n = (n + 1)/ 2
顺序查找的平均时间复杂度为O(N)

二:二分查找(有序表查找)

要点:二分查找又称折半查找,它是一种高效率的查找方法。

存储结构:使用二分查找需要2个前提:
第一:必须是顺序存储结构;
第二:必须是有序的表。

基本思想:
首先,将表中间位置的关键字与查找关键字进行比较,如果相等,则查找成功;
否则,利用中间位置记录将表分成前后两个子表,如果中间位置记录的关键字大于查找的关键字,则进一步查找中间位置关键字的前子表,否则,查找后子表。
重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。

python3代码实现:

# -*- coding: utf-8 -*-
"""
Created on Sat Jul 13 14:38:16 2019

@author: ZQQ
"""

def binarySearch(input_list, key):
    low = 0
    high = len(input_list) - 1 # 索引从0开始
    time = 0
    while low <= high:
        time += 1
        mid = int((low + high) / 2) # 取中间位置
        print('折半次数',time)
        if input_list[mid] == key:
            return mid # 查找成功,直接返回位置
        elif input_list[mid] < key:
            low = mid + 1
        else: # input_list[mid] > key
            high = mid - 1
            
    return False
            
if __name__ == '__main__':
    input_list = [1, 5, 7, 8, 11] # 必须是有序的顺序存储结构
    result = binarySearch(input_list, 8)
    print(result)  

运行结果:
在这里插入图片描述
算法分析:
二分查找的过程可看成一个二叉树。把查找区间的中间位置视为树的根,左区间和右区间视为根的左子树和右子树。由此得到的二叉树,称为二分查找的判定树或比较树。由此可知,二分查找的平均查找长度实际上就是树的高度O(logN)。
时间复杂度:O(logN)
优化:
插值算法,对mid进行改进
斐波那契查找。
详见https://www.cnblogs.com/feixuelove1009/p/6148357.html
也可以查找其他的相关资料。

三:分块查找(索引顺序查找)

对于海量的无序数据,为了提高查找速度,一般会为其构造索引表。
索引就是把一个关键字与它相对应的记录进行关联的过程。
一个索引由若干个索引项构成,每个索引项至少包含关键字和其对应的记录在存储器中的位置等信息。
索引按照结构可以分为:线性索引、树形索引和多级索引。
线性索引:将索引项的集合通过线性结构来组织,也叫索引表。
线性索引可分为:稠密索引、分块索引和倒排索引

1.稠密索引
稠密索引指的是在线性索引中,为数据集合中的每个记录都建立一个索引项

2.分块索引
给大量的无序数据集合进行分块处理,使得块内无序,块与块之间有序。
这其实是有序查找和无序查找的一种中间状态或者说妥协状态。因为数据量过大,建立完整的稠密索引耗时耗力,占用资源过多;但如果不做任何排序或者索引,那么遍历的查找也无法接受,只能折中,做一定程度的排序或索引。
在这里插入图片描述
3.倒排索引
不是由记录来确定属性值,而是由属性值来确定记录的位置,这种被称为倒排索引。其中记录号表存储具有相同次关键字的所有记录的地址或引用(可以是指向记录的指针或该记录的主关键字)。
倒排索引是最基础的搜索引擎索引技术。

要点:分块查找(Blocking Search)又称索引顺序查找。它是一种性能介于顺序查找和二分查找之间的查找方法。

分块查找由于只要求索引表是有序的,对块内节点没有排序要求,因此特别适合于节点动态变化的情况。

存储结构:分块查找表是由“分块有序”的线性表和索引表两部分构成的。

所谓“分块有序”的线性表,是指:假设要排序的表为R[0…N-1],将表均匀分成b块,前b-1块中记录个数为s=N/b,最后一块记录数小于等于s;每一块中的关键字不一定有序,但前一块中的最大关键字必须小于后一块中的最小关键字。这是使用分块查找的前提条件。

算法分析:
因为分块查找实际上是两次查找过程之和。若以二分查找来确定块,显然它的查找效率介于顺序查找和二分查找之间。

四:三种线性查找的比较

(1) 以平均查找长度而言,二分查找 > 分块查找 > 顺序查找。
(2) 从适用性而言,顺序查找无限制条件,二分查找仅适用于有序表,分块查找要求“分块有序”。
(3) 从存储结构而言,顺序查找和分块查找既可用于顺序表也可用于链表;而二分查找只适用于顺序表。
(4) 分块查找综合了顺序查找和二分查找的优点,既可以较为快速,也能使用动态变化的要求。

参考:

https://www.cnblogs.com/jingmoxukong/p/4324179.html

https://www.cnblogs.com/feixuelove1009/p/6148357.html

如若侵权,留言立删。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机器不学习我学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值