前段時間,我在 近期的大更新 中介紹了代碼中插入圖片注釋的功能,得到很多讀者的好評。
如果說圖片注釋是開胃小菜,這一次功能升級可以說是一步到位:我將所有算法代碼進行了動畫可視化,且全線支持我的刷題全家桶,包括 刷題網(wǎng)站、Chrome 插件、vscode 插件 和 Jetbrains 插件。
info:我的刷題全家桶下載安裝手冊 點這里。
可視化面板主要分為以下幾個部分:

在我的 網(wǎng)站首頁 就有一個示例,對單鏈表成環(huán)的算法進行了可視化:

再舉個二叉樹的例子:

注意,這些動畫不是一個簡單的視頻或者 GIF,而是交互式頁面,你可以自己控制動畫的播放,一步步查看代碼的運行過程:

上面展示的是將二叉樹「拉平」的算法執(zhí)行過程,每一步都會在左側(cè)高亮顯示代碼正在執(zhí)行的部分,并將算法當前的狀態(tài)可視化顯示在右側(cè),方便你更直觀地理解算法執(zhí)行邏輯。
以上是基本的可視化功能展示,下面來介紹點進階的功能。
遞歸過程的可視化
遞歸算法是很多讀者頭痛的,我之前寫過一篇 從二叉樹的角度理解一切遞歸算法,從理論上抽象出了遞歸算法最基本的思維模型和編寫技巧。
而現(xiàn)在我可以借助可視化面板,把遞歸算法的執(zhí)行過程可視化出來,讓你更直觀地理解遞歸算法的執(zhí)行過程。而且我對遞歸算法可視化的方式是我之前系列文章所闡述的算法思想的的具體實現(xiàn),絕對可以幫助你更好的理解算法的本質(zhì)。
在我的網(wǎng)站首頁就可以快速體驗:
https://labuladong.gitee.io/algo/
https://labuladong.github.io/algo/
我先簡單梳理一下我之前的文章對遞歸算法的闡述,然后再介紹一下這次的可視化更新為什么能幫助你更好的理解遞歸算法。
遞歸算法基礎(chǔ)梳理
首先,我在 我的算法學習心得 中說過,算法的本質(zhì)是窮舉,而大家普遍認為比較難的算法,比如回溯算法、動態(tài)規(guī)劃、DFS 算法等,它們的本質(zhì)也是窮舉,住不過需要借助遞歸的形式,或者說是遞歸的思想,來實現(xiàn)窮舉。
關(guān)于這些比較抽象的遞歸算法,我在 DFS/BFS/回溯/動歸算法的融會貫通 中用二叉樹這種簡單的基本結(jié)構(gòu)把它們都穿起來了,我把二叉樹系列算法分為兩種解題思路:
一種是分解問題的思維模式,這種思路代表著動態(tài)規(guī)劃、分治算法等;另一種是遍歷問題的解題思維模式,這種思路代表著回溯算法、DFS 算法等。
反過來,在用動態(tài)規(guī)劃/回溯算法等比較復雜的問題時,我也會教大家用樹的視角來理解算法,把遞歸函數(shù)理解成遞歸樹上的一個指針,比如 回溯算法秒殺排列/組合/子集問題 中我畫出了全排列問題的回溯樹:

在 動態(tài)規(guī)劃算法核心框架 中,我畫出了斐波那契問題的遞歸樹:

只要把遞歸樹畫出來,就可以很直觀地理解這些遞歸算法:回溯算法就是在遍歷一棵多叉樹,并收集葉子節(jié)點的值;動態(tài)規(guī)劃就是在分解問題,用子問題的答案來推導原問題的答案。
有了這些基礎(chǔ),我們再來看看這次的可視化更新。
遞歸算法的可視化
之前的可視化功能只支持數(shù)據(jù)結(jié)構(gòu)的可視化,比如說二叉樹、鏈表、數(shù)組等。而函數(shù)的遞歸過程是通過遞歸堆棧的可視化來體現(xiàn)的:

而現(xiàn)在,我可以將遞歸函數(shù)的遞歸過程抽象成遞歸樹,并且這棵遞歸樹會隨著算法的執(zhí)行動態(tài)生長,這樣就可以很直觀地看到遞歸算法的執(zhí)行過程了:

而且值得一提的是,這棵遞歸樹上每個節(jié)點的信息都是被我精心設(shè)計的。
比如說對于動態(tài)規(guī)劃算法這種分解問題的思路,我會把每個節(jié)點的值顯示為「狀態(tài)」,當遞歸節(jié)點對應(yīng)的遞歸調(diào)用結(jié)束之后,該節(jié)點也會記錄遞歸調(diào)用的結(jié)果,這樣就可以很直觀地理解問題是如何分解的,以及子問題的答案是如何推導出原問題的答案的。
舉個具體的例子,比如說 動態(tài)規(guī)劃算法核心框架 中講的斐波那契問題,我們把 fib(n) 的參數(shù) n 作為這個問題的「狀態(tài)」,那么節(jié)點的值就是每次遞歸調(diào)用的這個 n 的值。
當整個算法結(jié)束之后,我們就可以看到這棵遞歸樹的完整結(jié)構(gòu),鼠標移到一個節(jié)點上,還可以顯示該次遞歸調(diào)用的具體返回值:

這樣,我們就可以很直觀地看到問題的分解以及通過子問題的答案是推導原問題答案的過程。
另外,你也可以直觀地看到備忘錄剪枝的效果,比如這是不帶剪枝邏輯的斐波那契算法:

這是帶備忘錄剪枝邏輯的斐波那契算法:

是不是發(fā)現(xiàn)樹上的節(jié)點明顯少了很多?這就是備忘錄剪枝的效果,直不直觀?學習算法的門檻都給你降到這份上了,再說自己學不會,理解不了那真的是借口了吧~
當然,斐波那契這個問題很簡單,我只是拿來舉例方便大家理解。我的網(wǎng)站上的所有動態(tài)規(guī)劃題目都支持了類似的可視化,因為正如前文 DFS/BFS/回溯/動歸算法的融會貫通 所說,它們本質(zhì)都是樹。
再看看回溯算法,因為回溯算法是遍歷的思路,所以我會把每個節(jié)點的值顯示為「路徑」,記錄遍歷到當前節(jié)點經(jīng)過的路徑。比如說 回溯算法秒殺排列/組合/子集問題 中的全排列問題,這是算法最終執(zhí)行完成的樣子:

可以看到,這棵遞歸樹上的每個節(jié)點都記錄了從根節(jié)點到當前節(jié)點的路徑,每個葉子節(jié)點就是一個全排列的結(jié)果,和我之前畫的回溯樹一模一樣:

其實我覺得只要畫出遞歸樹已經(jīng)比較好理解了,但可視化面板是可交互的,執(zhí)行到的代碼會高亮顯示,你可以結(jié)合著代碼的執(zhí)行,更直觀地理解回溯算法的遍歷過程。
配套插件的支持
我的 網(wǎng)站、Chrome 插件、vscode 插件 和 Jetbrains 插件 的最新版本都全面支持了上述可視化面板,你可以在這些插件中直接使用這個功能。
Chrome 插件截圖:

vscode 插件截圖:

Jetbrains 插件截圖:

以上的所有工具/插件,可在我的網(wǎng)站首頁查看具體的安裝使用手冊:
https://labuladong.gitee.io/algo/
https://labuladong.github.io/algo/
更多高質(zhì)量干貨文章,請關(guān)注我的微信公眾號 labuladong 和算法博客 labuladong 的算法秘籍。