查找
在一些数据元素中,通过一定的方法找出与给定关键字相同的数据元素的过程。
列表查找
顺序查找:
从列表中从头到尾按顺序查找指定元素
输入:列表、待查找元素
输出:元素下标(未找到元素时一般返回None或-1)
内置列表查找函数:index()
示例:
# enumerate() 是 python 内置函数,可以直接使用,适用于列表、元组或字符串
# enumerate() 的作用就是按 序号(索引序列)+元素(值) 的形式将一个可迭代对象返回
# 通过 enumerate() 内置函数来将列表包装成生成器,直接取到其索引和值。
def find_element_from_list(lis, element):
for i, val in enumerate(lis):
if val == element:
return i
else:
return None
item = [i for i in range(9)]
print(item)
print(find_element_from_list(item, 0))
print(find_element_from_list(item, 9))
结果:
上述代码,也适用于查找列表、元组或字符串中的某个元素位置
如果列表中有多个同样的元素,上述代码只返回第一个,怎么返回所有元素下标呢?
代码如下:
import random
# 要查找的元素如果有多个,且都要返回位置
def find_element_from_list(lis, element):
num = 0
for i, val in enumerate(lis):
if val == element:
num = num + 1
print(f"元素位置为{i}")
if num != 0:
print(f"该容器中共有{num}个{element}")
else:
print("该容器中无此元素!")
item = [random.randint(0,9) for i in range(10)]
print(item)
find_element_from_list(item, 8)
结果:
顺序查找的时间复杂度为O(n)
二分查找
又叫折半查找,从有序列表的初始候选区li[0:n]开始,通过对待查找的值与候选区中间值的比较,可以使候选区减少一半
步骤:
1、确定候选区[left,rght]:left=0,right=len(list)-1
2、确定中间值,mid=(left+rght)//2,取整
3、循环:
while left <= right: #当左边界大于右边界时,即候选区没有数据时,结束循环,
4、循环内作判断:
如果list[mid]等于要找的值,就返回下标mid
如果list[mid]大于要找的值,即要找的值下标在mid的左边,此时候选区right应移动到mid的左边mid-1的位置
如果list[mid]小于要找的值,即要找的值下标在mid的右边,此时候选区left应移动到mid的右边mid+1的位置
5、循环外,如果循环执行结束都没找到,那么返回None
代码:
def binary_search(lis, element):
left = 0
right = len(lis) - 1 #确定候选区
while left <= right:
mid = (left + right)//2 # // 除法,得到一个整数
if lis[mid] == element:
return mid
elif lis[mid] > element:
right = mid - 1
else:
left = mid + 1
else:
return None
item = [i for i in range(9)]
print(item)
print(binary_search(item, 0))
print(binary_search(item, 1))
结果:
总结:
1、二分法查找时间复杂度:O(logn),所以对于同一个列表来说,二分法比顺序查找要花的时间更短
2、二分法只针对有序列表,所以,要是一个无序列表,要先排序(排序的时间复杂度为O(n)),所以针对无序列表,如果只进行一次查找的话,使用顺序查找,如果后续还要进行大量查找工作,那就先排序,后续使用二分查找