python算法9.17——分块查找/索引查找

一、

1.网上对于分块查找的分块部分尤其是python实现比较少,这里就按照个人的理解进行了编写,也基本达到分块的要求

1)面对一个未知序列,要将其分为m块,可以先确定各块的索引/最大值,然后将剩余元素排入各块

2)如何确定各块的最大值?最大块的索引为全表最大值,这需要一定操作,可以先放在一边,对于其他块,由于序列未知,各块元素数无要求,可以随机选取m-1个数作为索引,这里选取原表的前m-1个数排入第2~m个子表,然后对这几个元素进行排序,排序后将原表其余元素与索引比较后追加到对应子列表中

3)上述过程基本可以实现将一个未知序列分为m块子序列,但是在某些情况下(如果选取的原表前m-1个数包括最大值),第一个子序列会为空,这对后续的元素比较、追加、查找带来一定麻烦,并且也不满足m块的要求

2.针对最大值问题,对索引选取进行了优化改动,首先将原表的前m个元素升序排序,排序后选取前m-1个元素,保证了索引选取不到最大值

二、

1.

# 分块查找是对顺序查找、二分查找的综合优化,性能介于两者之间
# 基本原理:
# 1.将序列分为m块,块内部无序、外部有序
# 2.选取各块最大元素构成索引,对索引进行二分查找,找到所在的块
# 3.在确定块中用顺序查找
# 关键点:构建外部无序、内部有序的多子块

import random
Range = 20
Length = 9
flag = 0
pos = -1
tabNum = 3
tabPos = -1

list = random.sample(range(Range),Length)
goal = random.randint(0,Range)
print('search ',goal,', in list:')

# 子表建立,选择序列前m个元素排序后建立索引,根据索引建立子表
list_index = []                               #使用二维列表表示多个子序列
for i in range(tabNum):                      #在列表中添加m个列表
    list_index.append([])

for i in range(1,tabNum):                    #向第1-m子列表添加原序列的前m-1个元素作为索引,留出第一个子列表盛放最大索引,
    list_index[i].append(list[i-1])           # 但会出现最大值在第二个子列表中,第一子列表为空的情况
for i in range(1,tabNum-1):                  #将添加元素的子列表中的元素降序排列
    for j in range(1,tabNum-i):
        if list_index[j]<list_index[j+1]:
            list_index[j],list_index[j+1] = list_index[j+1],list_index[j]
# print(list_index)

for i in range(tabNum-1,Length):             #将其余元素添加到各子列表,比索引大则放到前一个子列表中,其余放入最后一个索引中
    for j in range(1,tabNum):
        if list[i]>list_index[j][0]:
            list_index[j-1].append(list[i])
            break
    else:
        list_index[tabNum-1].append(list[i])
# print(list_index)
if len(list_index[0]) > 1:                   #提取第一个子列表的最大值最为索引
    for i in range(len(list_index[0])-1,0,-1):
        if list_index[0][i]>list_index[0][i-1]:
            list_index[0][i],list_index[0][i-1]  =  list_index[0][i-1],list_index[0][i]
print(list_index)                            #显示构造的子列表

for i in range(tabNum-1,-1,-1):             #将给定元素与各子列表进行比较,确定给定元素位置
    if len(list_index[i]) != 0 and goal<list_index[i][0]:
        for j in range(len(list_index[i])):
            if list_index[i][j] == goal:
                tabPos = i+1
                pos = j+1
                flag = 1

if flag:
    print("find in ",tabPos,"list ",pos,"th place")
else:
    print("not found")

2.

# 更改索引选取,并对索引使用升序排序

import random
Range = 20
Length = 9
flag = 0
pos = -1
tabNum = 3
tabPos = -1

list = random.sample(range(Range),Length)
goal = random.randint(0,Range)
print('search ',goal,', in list:')

# 子表建立,选择序列前m个元素排序后建立索引,根据索引建立子表
list_index = []                               #使用二维列表表示多个子序列
for i in range(tabNum):                      #在列表中添加m个列表
    list_index.append([])
for i in range(tabNum):                      #将前m个元素升序
    for j in range(tabNum-1-i):
        if list[j]>list[j+1]:
            list[j],list[j+1] = list[j+1],list[j]
for i in range(tabNum-1):                    #向前1-m子列表添加原序列的前m-1个元素作为索引,留出第m个子列表盛放最大索引,
    list_index[i].append(list[i])
for i in range(tabNum-1,Length):             #将其余元素添加到各子列表,比索引小则放到本子列表中,其余放入最后一个索引中
    for j in range(tabNum-1):
        if list[i]<list_index[j][0]:
            list_index[j].append(list[i])
            break
    else:
        list_index[tabNum-1].append(list[i])


for i in range(len(list_index[tabNum-1])-1,0,-1):       #一次方向冒泡,将最大值提前
    if list_index[tabNum-1][i]>list_index[tabNum-1][i-1]:
        list_index[tabNum-1][i],list_index[tabNum-1][i-1]  =  list_index[tabNum-1][i-1],list_index[tabNum-1][i]
print(list_index)                            #显示构造的子列表

for i in range(tabNum):                     #将给定元素与各子列表进行比较,确定给定元素位置
    if goal<list_index[i][0]:
        for j in range(len(list_index[i])):
            if list_index[i][j] == goal:
                tabPos = i+1
                pos = j+1
                flag = 1
                break
        break

if flag:
    print("find in ",tabPos,"list ",pos,"th place")
else:
    print("not found")

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值