深度優先遍歷, 刷過題的朋友應該都很熟悉了,難是不難,可是理解起來仍是要費一些功夫的. 深度優先遍歷的實現方法有遞歸和非遞歸兩種, 這裏咱們用可視化的角度,講解前一種: 遞歸的深度優先遍歷.javascript
爲何要以可視化的方式來說解呢? 由於人是視覺的動物, 若是和你說 二叉樹
或 棧
, 相信你們腦中出現的都是下面的圖形:java
而不是下面的代碼:node
// binary tree class Node { constructor(value, leftChild, rightChild) { this.value = value this.leftChild = leftChild this.rightChild = rightChild } } // stack const stack = new Array() stack.push(1) var topItem = stack.pop()
因此說, 人是視覺動物, 以圖形可視化的方式來說解問題每每能講解的更清楚, 這也就是我寫本文的原因.git
爲了可視化的講解 深度優先遍歷算法
, 筆者寫了一個簡單的網頁, 實現的功能有:github
Start DFT
按鈕, 用戶將看到算法中用到的 二叉樹 和 棧 都將動態 的展現在頁面中,能夠直觀的看到代碼運行過程當中數據的變化頁面目前還在繼續優化中, 讓咱們看看目前的效果:算法
https://ssthouse.github.io/visual-explain/#/list/dft微信
能夠看到,網頁模擬了深度搜索時二叉樹和棧的動態變化過程:數據結構
其中頁面左上角爲初始遍歷的二叉樹數據, 用戶能夠修改二叉樹數據後再次啓動可視化深度優先遍歷過程.post
頁面左下角爲深度優先遍歷的 javascript 實現版本,做爲參考.優化
可視化分析以前,讓咱們先來簡單看看實現深度優先搜索的代碼:
export class Dft { constructor(rootNode, stepCallback) { this.rootNode = rootNode this.stepCallback = stepCallback } start() { if (!this.rootNode || !this.stepCallback) { return } const stack = [this.rootNode] while (stack.length !== 0) { const curNode = stack.pop() console.log(`current node: ${curNode.value}`) curNode.childrenNodes.forEach(element => { stack.push(element) }) } } } export class Node { constructor(value, childrenNodes = []) { this.value = value this.childrenNodes = childrenNodes } }
代碼不長,讓咱們一步步看.
首先咱們建立了一個棧 const stack = [this.rootNode]
, 並將根節點放入棧中.
接下來是一個while語句, 跳出循環的條件是 棧爲空, 也就是表明咱們遍歷完了整棵樹.
在循環中, 咱們先將棧頂的節點彈出, 並打印出來, 表示咱們已經遍歷過了該節點. 而後將該節點的全部子節點壓入棧中, 這就保障了咱們下一個遍歷到的點就是該節點的子節點. 重複該循環, 最後咱們就能夠看到, 二叉樹的每一個節點都按照深度搜索的順序被打印了出來:
current node: 1 current node: 4 current node: 7 current node: 6 current node: 2 current node: 5 current node: 3
若是是對棧的使用比較熟悉的同窗, 可能看到這裏就已經明白原理了.
可是, 若是是對棧使用不是很熟悉的同窗, 估計對代碼的執行過程仍是沒有一個直觀的認識, 那麼讓咱們以更直觀的方式看看這段代碼是怎麼運行的.
第一步, 將根節點壓入棧中:
接下來進入 while 循環, 每一個循環都會將棧頂的節點彈出, 將其子節點壓入棧中:
能夠看出, 深度優先遍歷利用了棧先進後出的特性, 使得對於每一個節點, 都將在遍歷該節點後,下一步遍歷他的子節點, 由此完成深度優先的遍歷:
本文中的二叉樹, 棧的可視化是筆者本身封裝的 UI 組件, 只需簡單的調用就能夠將代碼中數據結構以可視化的方式顯示在頁面中.
我的以爲這樣的數據結構可視化可能會對代碼的講解有些幫助, 若是你也有這方面的需求的話, 不妨在下面留言告訴我, 我能夠將這些 UI 組件封裝一下方便有須要的人使用.
https://github.com/ssthouse/visual-explain
這裏是個人 D3.js 、 數據可視化 的 github 地址, 歡迎 start & fork :tada:
郵箱: ssthouse@163.com
微信: