Python算法之二分查找(折半查找)

    查找有线性查找、二分查找、通过搜索树查找

1.二分查找是对有序表查找方式。

        二分查找(名折半查找)的查找过程:先确定待查找记录所在的范围(区间),然后逐步缩小范围直到 找到或 找不到 该记录为止。

        二分经常让手写,注意边界。

        时间复杂度为 :O(log2n),log以2为底 n 的对数,可以简写成 O(log n)。

        空间复杂度:递归形式复杂度O(n),递归一次要开辟一个空间。非递归形式复杂度O(1)。

方法一:使用普通方法实现(比递归效率高) , recursive /rɪ'kɜːsɪv/ 递归的,循环的

def binary_search(sorted_array, val):
	if not sorted_array:
		return -1
	
	beg = 0                       # 指向开头
	end = len(sorted_array) - 1   # 指向结尾
	
	while beg <= end:
		mid = int((beg + end) / 2)  # 为了屏蔽Python2/3差异,使用类型强转。
		if sorted_array[mid] == val:
			return mid
		elif sorted_array[mid] > val:
			end = mid - 1
		else:
			beg = mid + 1
	return -1		

def test_binary_search():
	array = [1, 2, 3, 4, 5, 6, 9, 10, 13, 17]
	print(array)
	print(binary_search(array, 17))

test_binary_search()

代码二:使用递归方法实现

def binary_search_recursive(sorted_array, beg, end, val):
	'''
	 递归方式实现二分,注意递归出口
	'''
	if beg > end:
		return -1
	mid = int((beg +end) / 2)   # 为了屏蔽Python2/3差异,使用类型强转。
	if sorted_array[mid] == val:
		return mid
	elif sorted_array[mid] > val:
		return binary_search_recursive(sorted_array, beg, mid -1, val)
	else:
		return binary_search_recursive(sorted_array, mid + 1, end, val)
	
	
def test_binary_search_recursive():
	array = [1, 2, 3, 4, 5, 6, 9, 10, 13, 17]
	print(array)
	print(binary_search_recursive(array, 0, 9, 17))

test_binary_search_recursive()

2.对无序表实现二分查找

     (注意:我这里是实现,说明对无序表不能直接进行二分查找)

        二分查找又称折半查找

        必须采用顺序存储结构

        必须按关键字大小有序排列(如果是一个乱序的列表,必须先进行排序,才能用二分查找

alist = [0, 1, 10, 88, 19, 9, 1]

def binary_search(arr, start, end, hkey):
	if start > end:
		return -1
	mid = int((start + end) / 2)    # 为了屏蔽Python2/3差异,使用类型强转。
	if arr[mid] > hkey:
		return binary_search(arr, start, mid - 1, hkey)
	if arr[mid] < hkey:
		return binary_search(arr, mid + 1, end, hkey)
	return mid
	
alist = sorted(alist)
print(alist)
print(binary_search(alist, 0, 6, 9))  # 返回已经排好序列表中9元素的位置

        注意:如果函数的参数列表中有指向数组开始和结尾的两个指针参数,可以使用递归实现二分查找;如果函数只有列表和目标值两个参数是无法使用递归实现的,因为使用递归肯定切片生成新的列表目标值的下标已经改变。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值