基于Rx.js与generator的排序算法可视化

一图胜千言,一张动图又胜过千张静图。

学习算法,与其在大部头的字里行间咬文嚼字,不如先登高望远,一览究竟。

排序是算法里的基础,有着前辈智慧的结晶。

点击下图,你将来到排序算法这座山顶,你可以使用默认设置,也可以稍作修改,然后点击 “开始排序”, 你将看到看到计算机是如何一步一步将一堆杂乱的数据排好序的。它是如此直观,你再也不会弄混各种排序算法了。

图中的 svg 图形是用 d3 生成的, d3 是前端数据可视化领域的翘楚,推荐!

《基于Rx.js与generator的排序算法可视化》

打开控制台,里面的代码不是丑化过的,一目了然,通俗易懂。只是,这里用了es6,老浏览就oo了。让该逝去的就逝去吧。

说明

本项目依赖 Rx.js, 这里用来将排序过程中的中间态数组变成数据流。 如果你还不知道 Rx.js, 强烈推荐,它的数据流思想是在事件循环基础上的进一步升华,是一个伟大的工具

const stream$ = Rx.Observable.create(observer => {
  try {

    const timer = setInterval(() => {
      const ret = gen.next()
      if (ret.done) {
        clearInterval(timer)
        observer.complete()
      } else {
        observer.next(ret.value)
      }
    }, 0)

    return function unsubscribe () {
      clearInterval(timer)
    }

  } catch (err) {
    observer.error(err)
  }
})

Meta.startTime = +new Date()
Meta.subscription = stream$.subscribe(arr => {
  update(arr)
  const endTime = +new Date()
  document.querySelector('#spendtime').innerHTML = endTime - Meta.startTime
})

generator 是一个可返回多次的函数,如下定义一个 generator:

// 选择排序
function *selectionSort (arr) {
  const len = arr.length

  for (let i = 0; i < len - 1; i++) {
    let min = i
    for (let j = i + 1; j < len; j++) {
      if (arr[j] < arr[min]) {
        min = j
      }
    }
    [arr[i], arr[min]] = [arr[min], arr[i]] // 解构赋值
    yield arr
  }
}

与函数不同的是,generator 定义时在 function 后面有个 *

let gen = selectionSort(arr) // 这里生成了一个generator
let ret = gen.next() // 每次调用generator.next(), yield arr 的arr会赋值给ret.value

gen.next()的返回值是这样的

{
    value: [123, 212, 12, 211, ...],
    done: false // or true
}

当 generator 函数体执行完了,done 被置为 true

当然,这里的介绍实在只是以管窥豹,唯一的价值是抛砖引玉。推荐阮一峯大神的 ECMA Script 6入门

—done—

点赞