折半查找是算法中減治策略的基本例子,實現起來也很簡單,但是在網上看到的圖片教程不覺得很乾巴麼??
這是一個簡單的實現:
def Reduction(lists, k):
"""
:param lists: 元素列表
:param k: 查找元素
:return: int,list
"""
list_scatters = [lists]
low = 0
high = len(lists) - 1
while low <= high:
mid = int((low + high) / 2)
if k < lists[mid]:
high = mid - 1
list_scatters.append(lists[low:high + 1])
elif k > lists[mid]:
low = mid + 1
list_scatters.append(lists[low:high + 1])
else:
return mid + 1, list_scatters
return 0, []
if __name__ == "__main__":
# lists = list(map(float, input("請按順序輸入要查找的表(以空格隔開):").split()))
lists = [_ for _ in range(31)]
k = float(input("請輸入想要查找的數字:"))
num, list_scatters = Reduction(lists, k)
if num != 0:
print("這個數字是你輸入的數字的第{}個".format(num))
if len(list_scatters[-1]) != 1:
list_scatters.append([k])
else:
pass
else:
print("查找失敗!")
結果就一個這,多幹巴…
所以我整了個這:(這個gif爲了能看的更加清晰,我設置的幀與幀間隔時間有點長(5秒),你們可別以爲是靜態圖啊…)
(這個例子和上面一樣,是0~30一共31個有序的點,查找第18個(序號爲17))
怎麼生成的呢?我用的是matplotlib.animation
中的FuncAnimation
畫動態圖:
先上源碼:
import matplotlib.pyplot as plt
import matplotlib.animation as animation
def Reduction(lists, k):
"""
:param lists: 元素列表
:param k: 查找元素
:return: int,list
"""
list_scatters = [lists]
low = 0
high = len(lists) - 1
while low <= high:
mid = int((low + high) / 2)
if k < lists[mid]:
high = mid - 1
list_scatters.append(lists[low:high + 1])
elif k > lists[mid]:
low = mid + 1
list_scatters.append(lists[low:high + 1])
else:
return mid + 1, list_scatters
return 0, []
def draw(list_scatters):
"""
:param list_scatters: list
:return: gif
"""
fig, ax = plt.subplots()
def init():
# 初始化函數用於繪製一塊乾淨的畫布,爲後續繪圖做準備
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['left'].set_color('none')
def update(lists):
plt.scatter(lists, [0 for _ in range(len(lists))], s=1 / len(lists) * 300)
plt.title("還剩{}個點".format(len(lists)))
plt.yticks(())
ani = animation.FuncAnimation(fig, update, frames=list_scatters, init_func=init, interval=5000)
ani.save("123.gif", writer='pillow')
if __name__ == "__main__":
# lists = list(map(float, input("請按順序輸入要查找的表(以空格隔開):").split()))
lists = [_ for _ in range(31)]
k = float(input("請輸入想要查找的數字:"))
num, list_scatters = Reduction(lists, k)
if num != 0:
print("這個數字是你輸入的數字的第{}個".format(num))
if len(list_scatters[-1]) != 1:
list_scatters.append([k])
else:
pass
# print(list_scatters)
draw(list_scatters)
else:
print("查找失敗!")
然後再說FuncAnimation
的參數:
第一個fig
可以理解爲動畫所在的畫布;
第二個update
就是每一幀的函數;
第三個frames
傳入的是update的參數;
第四個init_func
是初始化的圖形(代碼中對比的是init函數(去除上、左、右邊框));
第五個interval
就是幀與幀之間的間隔(延時(我這裏設置的是5秒));
…
還有一些其他的參數我沒有用到,可以去看官方文檔:
https://matplotlib.org/api/_as_gen/matplotlib.animation.FuncAnimation.html
想要系統學習matplotlib可以看這裏:
數據分析三劍客之 Matplotlib 基礎教程
最後…emm…再放一張圖吧: