可視化講解 深度優先遍歷(DFT)

可視化講解 深度優先遍歷(DFT)

深度優先遍歷, 刷過題的朋友應該都很熟悉了,難是不難,可是理解起來仍是要費一些功夫的. 深度優先遍歷的實現方法有遞歸非遞歸兩種, 這裏咱們用可視化的角度,講解前一種: 遞歸的深度優先遍歷.javascript

爲何要以可視化的方式來說解呢? 由於人是視覺的動物, 若是和你說 二叉樹 , 相信你們腦中出現的都是下面的圖形:java

binary tree

stack

而不是下面的代碼: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

  • 用戶可編輯進行深度遍歷的二叉樹
  • 網頁上給出了 JavaScript 版本的實現
  • 點擊 Start DFT 按鈕, 用戶將看到算法中用到的 二叉樹 都將動態 的展現在頁面中,能夠直觀的看到代碼運行過程當中數據的變化

頁面目前還在繼續優化中, 讓咱們看看目前的效果:算法

在線demo:

https://ssthouse.github.io/visual-explain/#/list/dft微信

stack

能夠看到,網頁模擬了深度搜索時二叉樹的動態變化過程:數據結構

  • 二叉樹中當前遍歷到的節點會變成紅色;
  • 棧中壓入 (push)的節點爲灰色;
  • 棧中彈出 (pop) 的節點會變爲紅色, 而後消失;

其中頁面左上角爲初始遍歷的二叉樹數據, 用戶能夠修改二叉樹數據後再次啓動可視化深度優先遍歷過程.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

若是是對棧的使用比較熟悉的同窗, 可能看到這裏就已經明白原理了.

可是, 若是是對棧使用不是很熟悉的同窗, 估計對代碼的執行過程仍是沒有一個直觀的認識, 那麼讓咱們以更直觀的方式看看這段代碼是怎麼運行的.

可視化講解

第一步, 將根節點壓入棧中:

step1

接下來進入 while 循環, 每一個循環都會將棧頂的節點彈出, 將其子節點壓入棧中:

step2

能夠看出, 深度優先遍歷利用了棧先進後出的特性, 使得對於每一個節點, 都將在遍歷該節點後,下一步遍歷他的子節點, 由此完成深度優先的遍歷:

stack

最後

本文中的二叉樹, 的可視化是筆者本身封裝的 UI 組件, 只需簡單的調用就能夠將代碼中數據結構以可視化的方式顯示在頁面中.

我的以爲這樣的數據結構可視化可能會對代碼的講解有些幫助, 若是你也有這方面的需求的話, 不妨在下面留言告訴我, 我能夠將這些 UI 組件封裝一下方便有須要的人使用.

源碼在這, 歡迎 fork & star

https://github.com/ssthouse/visual-explain

想繼續瞭解 D3.js || 數據可視化 ?

這裏是個人 D3.js數據可視化 的 github 地址, 歡迎 start & fork :tada:

D3-blog

若是以爲不錯的話, 不妨點擊下面的連接關注一下 : )

github 主頁

知乎專欄

掘金

想直接聯繫我 ?

郵箱: ssthouse@163.com

微信:

wechat

相關文章
相關標籤/搜索