@rimbu/graph
Version:
Immutable Graph data structures for TypeScript
120 lines • 5.36 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.traverseBreadthFirstCustom = traverseBreadthFirstCustom;
exports.traverseBreadthFirstHashed = traverseBreadthFirstHashed;
exports.traverseBreadthFirstSorted = traverseBreadthFirstSorted;
var tslib_1 = require("tslib");
var common_1 = require("@rimbu/common");
var hashed_1 = require("@rimbu/hashed");
var sorted_1 = require("@rimbu/sorted");
var stream_1 = require("@rimbu/stream");
var custom_1 = require("@rimbu/stream/custom");
var GraphBreadthFirstStream = /** @class */ (function (_super) {
tslib_1.__extends(GraphBreadthFirstStream, _super);
function GraphBreadthFirstStream(node, graph, addVisitedNode) {
var _this = _super.call(this) || this;
_this.node = node;
_this.graph = graph;
_this.addVisitedNode = addVisitedNode;
return _this;
}
GraphBreadthFirstStream.prototype[Symbol.iterator] = function () {
return new DirectedGraphBreadthFirstIterable(this.node, this.graph, this.addVisitedNode);
};
return GraphBreadthFirstStream;
}(custom_1.StreamBase));
var DirectedGraphBreadthFirstIterable = /** @class */ (function (_super) {
tslib_1.__extends(DirectedGraphBreadthFirstIterable, _super);
function DirectedGraphBreadthFirstIterable(node, graph, addVisitedNode) {
var _this = _super.call(this) || this;
_this.node = node;
_this.graph = graph;
_this.addVisitedNode = addVisitedNode;
_this.nextIterators = [];
addVisitedNode(node);
var startConnectionStream = _this.graph.getConnectionStreamFrom(_this.node);
_this.currentIterator = startConnectionStream[Symbol.iterator]();
return _this;
}
DirectedGraphBreadthFirstIterable.prototype.fastNext = function (otherwise) {
var nextConnection;
while (undefined !== (nextConnection = this.currentIterator.fastNext())) {
var result = nextConnection;
var targetNode = result[1];
if (this.addVisitedNode(targetNode)) {
var targetConnectionStream = this.graph.getConnectionStreamFrom(targetNode);
this.nextIterators.push(targetConnectionStream[Symbol.iterator]());
return result;
}
}
var nextIterator = this.nextIterators.shift();
if (undefined === nextIterator)
return (0, common_1.OptLazy)(otherwise);
this.currentIterator = nextIterator;
return this.fastNext(otherwise);
};
return DirectedGraphBreadthFirstIterable;
}(custom_1.FastIteratorBase));
/**
* Returns a stream of connections that can be reached in the given `graph`
* starting at the given `startNode`, and using breadth-first traversal. It can
* avoid loops if needed in a custom way by supplying the `addVisitedNode` function.
* @param graph - the graph to traverse
* @param startNode - the start node within the graph
* @param addVisitedNode - a function taking the currenty traversed node,
* and returning true if the node has been traversed before, or false otherwise
* @example
* ```ts
* const g = EdgeGraphHashed.of([1, 2], [2, 3], [1, 3], [3, 4])
* const stream = traverseBreadthFirstCustom(g, 1)
* console.log(stream.toArray())
* // => [[1, 2], [1, 3], [2, 3], [3, 4]]
* ```
*/
function traverseBreadthFirstCustom(graph, startNode, addVisitedNode) {
if (addVisitedNode === void 0) { addVisitedNode = function () { return true; }; }
if (!graph.nonEmpty() || !graph.hasNode(startNode))
return stream_1.Stream.empty();
return new GraphBreadthFirstStream(startNode, graph, addVisitedNode);
}
/**
* Returns a stream of connections that can be reached in the given `graph`
* starting at the given `startNode`, and using breadth-first traversal. It avoids
* loops by internally placing the visited nodes in a HashSet builder.
* @param graph - the graph to traverse
* @param startNode - the start node within the graph
* @example
* ```ts
* const g = EdgeGraphHashed.of([1, 2], [2, 3], [1, 3], [3, 4])
* const stream = traverseBreadthFirstHashed(g, 1)
* console.log(stream.toArray())
* // => [[1, 2], [1, 3], [2, 3], [3, 4]]
* ```
*/
function traverseBreadthFirstHashed(graph, startNode) {
if (!graph.nonEmpty() || !graph.hasNode(startNode))
return stream_1.Stream.empty();
var visitSet = hashed_1.HashSet.builder();
return new GraphBreadthFirstStream(startNode, graph, visitSet.add);
}
/**
* Returns a stream of connections that can be reached in the given `graph`
* starting at the given `startNode`, and using breadth-first traversal. It avoids
* loops by internally placing the visited nodes in a SortedSet builder.
* @param graph - the graph to traverse
* @param startNode - the start node within the graph
* @example
* ```ts
* const g = EdgeGraphHashed.of([1, 2], [2, 3], [1, 3], [3, 4])
* const stream = traverseBreadthFirstSorted(g, 1)
* console.log(stream.toArray())
* // => [[1, 2], [1, 3], [2, 3], [3, 4]]
* ```
*/
function traverseBreadthFirstSorted(graph, startNode) {
if (!graph.nonEmpty() || !graph.hasNode(startNode))
return stream_1.Stream.empty();
var visitSet = sorted_1.SortedSet.builder();
return new GraphBreadthFirstStream(startNode, graph, visitSet.add);
}
//# sourceMappingURL=traverse-breadth-first.cjs.map