2分探索
二分探索(にぶんたんさく、英: binary search、BS)やバイナリサーチとは、ソート済み配列に対する探索アルゴリズムの一つ。
出典: フリー百科事典『ウィキペディア(Wikipedia)』
ソート済みのリストにおいて、 目標との中央の値の大小関係により、目標が中央の値の右にあるか、左にあるかを判断することで、目標のある場所を絞り込んでいく検索アルゴリズムです。
時間計算量は O(logn) 、空間計算量は O(1) になります。
import random
def binary_search(lst, target_val):
low = 0
high = len(lst) - 1
while low <= high:
mid = (low + high) // 2
if lst[mid] > target_val:
high = mid - 1
elif lst[mid] < target_val:
low = mid + 1
else:
return mid
return False
def print_serach_result(lst, target_val):
target_index = binary_search(lst, target_val)
if target_index:
print(f'{target_val}は{target_index+1}番目に見つかりました。')
else:
print(f'{target_val}はリストの中にありません。')
if __name__ == '__main__':
# 適当なリストの生成
random.seed(1)
lst = [random.randint(1, 100) for _ in range(10)]
lst.sort()
# [9, 16, 18, 33, 58, 61, 64, 73, 98, 98]
print(lst)
# 線形探索
# 64は7番目に見つかりました。
print_serach_result(lst, 64)
# 63はリストの中にありません。
print_serach_result(lst, 63)
import random
def binary_search(lst, target_val):
low = 0
high = len(lst) - 1
while low <= high:
mid = (low + high) // 2
if lst[mid] > target_val:
high = mid - 1
elif lst[mid] < target_val:
low = mid + 1
else:
return mid
return False
def print_serach_result(lst, target_val):
target_index = binary_search(lst, target_val)
if target_index:
print(f'{target_val}は{target_index+1}番目に見つかりました。')
else:
print(f'{target_val}はリストの中にありません。')
if __name__ == '__main__':
# 適当なリストの生成
random.seed(1)
lst = [random.randint(1, 100) for _ in range(10)]
lst.sort()
# [9, 16, 18, 33, 58, 61, 64, 73, 98, 98]
print(lst)
# 線形探索
# 64は7番目に見つかりました。
print_serach_result(lst, 64)
# 63はリストの中にありません。
print_serach_result(lst, 63)
import random def binary_search(lst, target_val): low = 0 high = len(lst) - 1 while low <= high: mid = (low + high) // 2 if lst[mid] > target_val: high = mid - 1 elif lst[mid] < target_val: low = mid + 1 else: return mid return False def print_serach_result(lst, target_val): target_index = binary_search(lst, target_val) if target_index: print(f'{target_val}は{target_index+1}番目に見つかりました。') else: print(f'{target_val}はリストの中にありません。') if __name__ == '__main__': # 適当なリストの生成 random.seed(1) lst = [random.randint(1, 100) for _ in range(10)] lst.sort() # [9, 16, 18, 33, 58, 61, 64, 73, 98, 98] print(lst) # 線形探索 # 64は7番目に見つかりました。 print_serach_result(lst, 64) # 63はリストの中にありません。 print_serach_result(lst, 63)
想定通りの結果を得ることができました。
また、再帰を用いてコードを記述してみます。
import random
def binary_search_recursive(lst, target_val, low=0, high=-1):
if not lst:
return False
if high == -1:
high = len(lst) -1
if low == high:
if lst[low] == target_val:
return low
else:
return False
mid = low + (high -low) // 2
if lst[mid] > target_val:
return binary_search_recursive(lst, target_val, low, mid-1)
elif lst[mid] < target_val:
return binary_search_recursive(lst, target_val, mid+1, high)
else:
return mid
def print_serach_result(lst, target_val):
target_index = binary_search_recursive(lst, target_val)
if target_index:
print(f'{target_val}は{target_index+1}番目に見つかりました。')
else:
print(f'{target_val}はリストの中にありません。')
if __name__ == '__main__':
# 適当なリストの生成
random.seed(1)
lst = [random.randint(1, 100) for _ in range(10)]
lst.sort()
# [9, 16, 18, 33, 58, 61, 64, 73, 98, 98]
print(lst)
# 線形探索
# 64は7番目に見つかりました。
print_serach_result(lst, 64)
# 63はリストの中にありません。
print_serach_result(lst, 63)
import random
def binary_search_recursive(lst, target_val, low=0, high=-1):
if not lst:
return False
if high == -1:
high = len(lst) -1
if low == high:
if lst[low] == target_val:
return low
else:
return False
mid = low + (high -low) // 2
if lst[mid] > target_val:
return binary_search_recursive(lst, target_val, low, mid-1)
elif lst[mid] < target_val:
return binary_search_recursive(lst, target_val, mid+1, high)
else:
return mid
def print_serach_result(lst, target_val):
target_index = binary_search_recursive(lst, target_val)
if target_index:
print(f'{target_val}は{target_index+1}番目に見つかりました。')
else:
print(f'{target_val}はリストの中にありません。')
if __name__ == '__main__':
# 適当なリストの生成
random.seed(1)
lst = [random.randint(1, 100) for _ in range(10)]
lst.sort()
# [9, 16, 18, 33, 58, 61, 64, 73, 98, 98]
print(lst)
# 線形探索
# 64は7番目に見つかりました。
print_serach_result(lst, 64)
# 63はリストの中にありません。
print_serach_result(lst, 63)
import random def binary_search_recursive(lst, target_val, low=0, high=-1): if not lst: return False if high == -1: high = len(lst) -1 if low == high: if lst[low] == target_val: return low else: return False mid = low + (high -low) // 2 if lst[mid] > target_val: return binary_search_recursive(lst, target_val, low, mid-1) elif lst[mid] < target_val: return binary_search_recursive(lst, target_val, mid+1, high) else: return mid def print_serach_result(lst, target_val): target_index = binary_search_recursive(lst, target_val) if target_index: print(f'{target_val}は{target_index+1}番目に見つかりました。') else: print(f'{target_val}はリストの中にありません。') if __name__ == '__main__': # 適当なリストの生成 random.seed(1) lst = [random.randint(1, 100) for _ in range(10)] lst.sort() # [9, 16, 18, 33, 58, 61, 64, 73, 98, 98] print(lst) # 線形探索 # 64は7番目に見つかりました。 print_serach_result(lst, 64) # 63はリストの中にありません。 print_serach_result(lst, 63)
こちらも想定通りの結果を得ることができました。