折半查找是算法中减治策略的基本例子,实现起来也很简单,但是在网上看到的图片教程不觉得很干巴么??
这是一个简单的实现:
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…再放一张图吧: