topsort.js 711 B

1234567891011121314151617181920212223242526272829303132333435
  1. const _ = require('../lodash')
  2. module.exports = topsort
  3. topsort.CycleException = CycleException
  4. function topsort (g) {
  5. const visited = {}
  6. const stack = {}
  7. const results = []
  8. function visit (node) {
  9. if (_.has(stack, node)) {
  10. throw new CycleException()
  11. }
  12. if (!_.has(visited, node)) {
  13. stack[node] = true
  14. visited[node] = true
  15. _.each(g.predecessors(node), visit)
  16. delete stack[node]
  17. results.push(node)
  18. }
  19. }
  20. _.each(g.sinks(), visit)
  21. if (_.size(visited) !== g.nodeCount()) {
  22. throw new CycleException()
  23. }
  24. return results
  25. }
  26. function CycleException () {}
  27. CycleException.prototype = new Error() // must be an instance of Error to pass testing