目录
一、基本介绍
1、查找方法有:
顺序查找、二分查找、插值查找、斐波那契查找、树表查找、分块查找、哈希查找
2、在Python中,我们应当掌握两种常见的查找方法:
顺序查找、二分查找
二、顺序查找
1、顺序查找案例
有一个列表:白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王,猜名字游戏:从键盘中任意输入一个名称,判断列表中是否包含此名称[顺序查找] 要求:如果找到了,就提示找到,并给出下标值
# 如果只是完成查找功能,可以直接使用 list的方法 index
names_list = ["白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王"]
find_name="金毛狮王"
# 使用 list.index 完成查找
res_index=names_list.index(find_name)
print(f"res_index:{res_index}") # 1
# 顺序查找
# 定义列表
names_list = ["白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王"]
find_name="金毛狮王"
# 编写顺序查找函数
def seq_search(my_list,find_val):
"""
功能:顺序查找指定的元素
:param my_list: 传入的列表(即要查找的列表)
:param find_val: 要查找的值/元素
:return: 如果查找到则返回对应的索引下标,否则返回-1
"""
"""
思路分析
1、对列表进行遍历,如果找到返回对应的下标
2、如果遍历结束,没有找到,则返回-1
"""
find_index=-1
# 遍历
for i in range(len(my_list)):
# 开始比较,如果当前的元素就是要查找的元素,则返回索引
if my_list[i]==find_val:
print(f"恭喜,找到对应的值{find_val} 下标是{i}")
find_index=i
break # 退出for
else:
print(f"没有找到对应的值 {find_val}")
return find_index
# 测试
res_index=seq_search(names_list, find_name)
print("res_index:", res_index)
2、扩展:
如果一个列表中有多个要查找的元素/值,比如前面的列表有两个金毛狮王,请思考,怎样才能把满足查询条件的元素下标,都返回
# 顺序查找扩展
# 定义列表
names_list = ["白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王", "金毛狮王"]
find_name="金毛狮王"
# 编写顺序查找函数
def seq_search(my_list, find_val):
"""
思路分析:
1、顺序查找列表,把满足查询条件的元素下标都返回
2、定义一个空列表,保存查找到的索引下标,发现一个就动态的添加到列表
3、最后返回列表
"""
# 定义一个空列表
find_index=[]
# 遍历
for i in range(len(my_list)):
# 开始比较,如果当前的元素就是要查找的元素,就保存到 find_index
if my_list[i]==find_val:
# 将找到的下标,添加到 find_index
find_index.append(i)
# 返回列表
return find_index
# 测试
res_index=seq_search(names_list, find_name)
print("res_index:", res_index) # [1, 4]
三、二分查找
1、二分查找案例
请对一个列表(元素是从小到大的顺序的)进行二分查找[1,8,10,89,1000,1234],输入一个数,看看该列表中是否存在此数,并且求出下标,如果没有就返回-1
2、二分查找的思路分析
前提:该列表是一个排好序的列表(以从小到大为例)
1)找到列表的中间数 mid_val 和 find_val 比较
2)如果 find_val<mid_val,则到 mid_val 的左边查找
3)如果 find_val>mid_val,则到 mid_val 的右边查找
4)如果 find_val==mid_val,则找到,返回对应的下标即可
5)不断地重复 1-4 步骤,这里就是不断减半,使用while
6)如果while结束,都没有找到,说明find_val 没有在列表中
3、代码实现
# 要查找的列表
num_list = [1, 8, 10, 89, 1000, 1234]
# 编写二分查找函数
def binary_search(my_list,find_val):
"""
功能:完成二分查找
:param my_list:要查找的列表(该列表是有序的)
:param find_val: 要查找的元素/值
:return: 如果找到返回对应的下标,如果找不到返回-1
"""
# left_index:表示左边的索引
# right_index:表示右边的索引
left_index = 0
right_index = len(my_list)-1
# 定义找到数的下标
find_index=-1
# 使用while循环,不断的折半比较,比较的前提是 left_index<=right_index
while left_index<=right_index:
# 中间数的下标/索引
mid_index=(left_index+right_index)//2
# 如果 find_val<mid_val,则到 mid_val 的左边查找
if find_val<my_list[mid_index]:
right_index=mid_index-1
# 如果 find_val>mid_val,则到 mid_val 的右边查找
elif find_val>my_list[mid_index]:
left_index=mid_index+1
else: #相等
find_index=mid_index
break
return find_index
# 测试
res_index=binary_search(num_list, 1)
if res_index==-1:
print("没有找到该数")
else:
print(f"找到数,对应的下标 {res_index}")
4、 二分查找的注意事项和细节
1)二分查找的前提是该列表已经是一个排好序的列表(从小到大或从大到小)
2)排序的顺序是从小到大还是从大到小,会影响二分查找的代码逻辑
- num_list=[1234,1000,89,10,8,1] (从大到小)
- 思路与从小到大相似,但查找方向会发生改变