经典算法 之 索引查找 python实现


活动地址:CSDN21天学习挑战赛


1.查找算法

查找(Searching)是指根据某个给定的值,在表中根据一个关键字查找是否存在和这个关键字有关的数据元素或记录。简单来说,就是在我们定义的数据结构中,查找位于某个位置的数据。查找根据操作方式不同分为静态查找和动态查找两种,前者是仅获取数据不进行其他操作,后者则需要动态改变数据,比如在查找过程中插入新数据,或者删除某个已存在的数据。


基本概念

  • 查找表(Search Table):由同一类型的数据元素构成的集合
  • 查找(Searching):根据给定的某个值,在查找表中确定其一个关键字等于给定值的数据元素
  • 关键字:是数据元素的某个数据项的值,能够标识列表中的一个或一组数据元素。如果一个关键字能够唯一标识列表中的一个数据元素,则称其为主关键字,否则称为次关键字。当数据元素中仅有一个数据项时,数据元素的值就是关键字。
  • 主键(Primary Key):可唯一地标识某个数据元素或记录的关键字列表,是由同一类型的数据元素或记录构成的集合,可以使用任意数据结构实现
  • 平均查找长度:为了确定数据元素在列表中的位置,需要将关键字个数的期望值与指定值进行比较,这个期望值被称为查找算法在查找成功时的平均查找长度。如果列表的长度为n,查找成功时的平均查找长度为:
    A S L = P 1 C 1 + P 2 C 2 + . . . + P n C n = ∑ i = 1 n P i C i ASL = P_1C_1 + P_2C_2 + ... +P_nC_n = \sum\limits_{i=1}^n P_iC_i ASL=P1C1+P2C2+...+PnCn=i=1nPiCi

不同查找算法分类

顺序查找、二分查找(折半查找)、插值查找、斐波那契查找、树表查找、分块查找和哈希查找


2. 索引查找

  • 输入
    主数据:n个数的序列,通常直接存放在数组中,可以是任何顺序。
    基于主数据建立的索引表,索引表中的每个元素存储两个属性:关键字、主数据表中的序号,索引表按关键字有序。
    待查找元素key。

  • 输出
    查找成功:返回元素所在位置的编号。
    查找失败:返回-1或自定义失败标识。

算法说明
基本索引查找是基于一个有序的索引表进行折半查找,然后再根据索引表与主数据表的关系确定数据所在位置的过程。所以只需要在折半查找后,从索引表中取出该元素在主数据集合中对应的位置即可。

伪代码

left = 1
right = T.length
position = -1
while left <= right
    mid = (left + right) / 2
    if T[mid].key == key
        position = mid
        break
    else if T[mid] > key
        right = mid - 1
    else
        left = mid + 1
if position != -1
    return T[position].pos
else
    return -1

算法评价

  • 时间复杂度: O ( log ⁡ 2 n ) O(\log_2 n) O(log2n)
  • 空间复杂度: O ( n ) O(n) O(n)

3. 算法实践(Python)

索引查找

class IndexTable:
    def __init__(self):
        self.data = []
        self.key = []
    def CreatIndexTable(self,elements,n,s):
        t = n // s;
        for i in range (0,len(elements),t):
            self.data.append(i)
            self.key.append(max(elements[i:i+t]))
        return self.data,self.key
class StaticTable:
    def __init__(self):
        self.SequenceList = []        
    def CreateStaticTable(self,elements):
        self.SequenceList= elements 
    def IndexSearch(self,key,FirstPosList,MaxValueList):
        iPos = -1
        low = 0
        high = 0
        num = FirstPosList[1] - FirstPosList[0]
        for i  in range(len(FirstPosList)):
            if key <= MaxValueList[i]:
                low = 0
                high = low+num
                break
            elif key > MaxValueList[i] and key <= MaxValueList[i+1]:
                low = FirstPosList[i+1]
                high = low+num
                break
        '''此处也可以用折半查找,这里用的是顺序查找'''
        if high is not 0:
            for i  in range(low,high):
                if key == self.SequenceList[i]:
                    return i
        else:
            return iPos
            
if __name__ == '__main__':
    test = IndexTable()
    elements = [3,5,22,8,54,36,29,24,63,67,80,102]
    FirstPosList,MaxValueList = test.CreatIndexTable(elements,len(elements),3)
    table1 = StaticTable()
    table1.CreateStaticTable(elements)
    iPos = table1.IndexSearch(80,FirstPosList,MaxValueList)
    print("位置为:%d"  %iPos)

参考

1.一文学懂经典算法系列之:折半查找
2.张清云.《Python数据结构学习笔记》(ISBN:9787113269999)
3.python之查找(顺序查找、折半查找、索引查找、二叉排序树查找、哈希表查找)


@夏日回

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值