可视化讲解 深度优先遍历(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/vi...微信

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/v...

想继续了解 D3.js || 数据可视化 ?

这里是个人 D3.js数据可视化 的 github 地址, 欢迎 start & fork

D3-blog

若是以为不错的话, 不妨点击下面的连接关注一下 : )

github 主页

知乎专栏

掘金

想直接联系我 ?

邮箱: ssthouse@163.com

微信:

wechat

相关文章
相关标签/搜索