Python实现折半查找并用matplotlib实现动态过程可视化

折半查找是算法中减治策略的基本例子,实现起来也很简单,但是在网上看到的图片教程不觉得很干巴么??
在这里插入图片描述

这是一个简单的实现:


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…再放一张图吧:
在这里插入图片描述


Bye!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章