一、
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")