一. 二分法的適用條件
二分法查找適用於數據量較大時, 但是數據需要先排好順序.
優點: 二分法查找效率特別高
缺點: 二分法只適用於有序序列
二. 二分法的主要思想是:
設查找的數組區間為array[low, high]
(1)確定該區間的中間位置k
(2)將查找的值T與array[k]比較. 若相等, 查找成功返回此位置, 否則確定新的查找區域, 繼續二分查找.
區域確定如下: 1) T < array[k] 由數組的有序性可知T < array[k,k+1,……,high], 故新的區間為array[low,……,k-1]
2) T > array[k] 由數組的有序性可知T > array[low,……,k-1], 故新的區間為array[k,k+1,……,high]
每一次查找與中間值比較, 可以確定是否查找成功,不成功則當前查找區間將縮小一半, 遞歸查找即可.
三. 例題: 用二分法查找一個數是否在隨機數列中
1. 方法1(使用while循環):
步驟1: 拿到一個有100個隨機數的列表
import random # 引入一個隨機數模塊
def random_100(amount):
li = []
for i in range(amount): # 循環多少次就拿多少個隨機數
s = random.randint(0, 100)
li.append(s)
return li # 返回隨機數列表
lst = sorted(random_100(100)) # count=100 拿到由100個隨機數組成的列表lst,並將其排序(默認為升序)
步驟2: 任意輸入一個數(范圍是0~100),查看它是否在隨機數列表中
n = int(input("請輸入一個數:"))
left = 0 # 左臨界點left = 0
right = len(lst) - 1 # 右臨界點right = len(lst) - 1
while left <= right:
mid = (left + right) // 2 # 索引只能是整數,因此用地板除
if n > lst[mid]:
left = mid + 1
elif n < lst[mid]:
right = mid - 1
elif n == lst[mid]:
print("你輸入的數在這個列表中,它的位置是{}".format(mid))
break
else:
print("你輸入的數不在這個數列中")
2. 方法2: 使用遞歸函數
步驟1:
# 仍然引入隨機數模塊, 拿到一個隨機數列表
import random
def random_100(amount):
li = []
for i in range(amount):
s = random.randint(0, 100)
li.append(s)
return li
lst = sorted(random_100(100))
步驟2:
# 定義一個遞歸函數
def func(n, lst):
left = 0 # 左臨界點
right = len(lst) - 1 # 右臨界點
if left <= right:
mid = (left + right) // 2
if n < lst[mid]:
new_lst = lst[:mid]
return func(n, new_lst)
elif n > lst[mid]:
new_lst = lst[mid + 1:]
return func(n, new_lst)
else:
print("你輸入的數在這個列表中\n")
return True
else:
print("你輸入的數不在這個列表中\n")
return False
步驟3:
while 1:
n = int(input("請輸入你要查找的數:"))
func(n, lst)
3. 方法3: 使用遞歸函數(方法2的優化)
# 仍然引入隨機數模塊, 拿到一個隨機數列表
import random
def random_100(amount):
li = []
for i in range(amount):
s = random.randint(0, 100)
li.append(s)
return li
lst = sorted(random_100(100))
# 定義一個遞歸函數
def func(n, lst, left=0, right=None):
if right == None:
right = len(lst) - 1
if left <= right:
mid = (left + right) // 2
if n < lst[mid]:
right = mid - 1
elif n > lst[mid]:
left = mid + 1
else:
print("你輸入的數在這個列表中,它的位置{}\n".format(mid))
return True
return func(n, lst, left, right)
else:
print("你輸入的數不在這個列表中\n")
return False
while 1:
n = int(input("請輸入你要查找的數:"))
func(n, lst)