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!

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