mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-09-20 07:43:04 +08:00
Merge 89c86e76fc
into ca3d16dcce
This commit is contained in:
commit
8800eb6fb3
@ -0,0 +1,44 @@
|
||||
import GraphVertex from '../../../../data-structures/graph/GraphVertex';
|
||||
import GraphEdge from '../../../../data-structures/graph/GraphEdge';
|
||||
import Graph from '../../../../data-structures/graph/Graph';
|
||||
import topologicalSort from '../topologicalSortByCounting';
|
||||
|
||||
describe('topologicalSortByCounting', () => {
|
||||
it('should do topological sorting on graph', () => {
|
||||
const vertexNames = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'];
|
||||
const edges = [
|
||||
{ start: 'A', end: 'C' },
|
||||
{ start: 'A', end: 'G' },
|
||||
{ start: 'A', end: 'I' },
|
||||
{ start: 'B', end: 'C' },
|
||||
{ start: 'B', end: 'D' },
|
||||
{ start: 'C', end: 'E' },
|
||||
{ start: 'D', end: 'F' },
|
||||
{ start: 'E', end: 'F' },
|
||||
{ start: 'E', end: 'H' },
|
||||
{ start: 'F', end: 'G' },
|
||||
];
|
||||
const nameToVertex = {};
|
||||
const graph = new Graph(true);
|
||||
|
||||
vertexNames.forEach((name) => {
|
||||
const vertex = new GraphVertex(name);
|
||||
nameToVertex[name] = vertex;
|
||||
});
|
||||
edges.forEach((edge) => {
|
||||
const startVertex = nameToVertex[edge.start];
|
||||
const endVertex = nameToVertex[edge.end];
|
||||
|
||||
graph.addEdge(new GraphEdge(startVertex, endVertex));
|
||||
});
|
||||
|
||||
const sortedVertices = topologicalSort(graph);
|
||||
|
||||
expect(sortedVertices).toBeDefined();
|
||||
expect(sortedVertices.length).toBe(graph.getAllVertices().length);
|
||||
graph.getAllEdges().forEach((edge) => {
|
||||
expect(sortedVertices.indexOf(edge.startVertex))
|
||||
.toBeLessThan(sortedVertices.indexOf(edge.endVertex));
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,45 @@
|
||||
import PriorityQueue from '../../../data-structures/priority-queue/PriorityQueue';
|
||||
|
||||
/**
|
||||
* @param {Graph} graph
|
||||
* Implements Khan's algorithms
|
||||
*/
|
||||
export default function topologicalSort(graph) {
|
||||
// Count the preceders for all ndoes.
|
||||
const precederCounts = {};
|
||||
|
||||
// Order nodes by number of preceders.
|
||||
const priorityQueue = new PriorityQueue();
|
||||
|
||||
// The resulting sorted list.
|
||||
const sortedStack = [];
|
||||
|
||||
// Initialize the counter array.
|
||||
graph.getAllVertices().forEach((vertex) => {
|
||||
precederCounts[vertex.getKey()] = 0;
|
||||
});
|
||||
|
||||
// Count preceders for all nodes.
|
||||
graph.getAllEdges().forEach((edge) => {
|
||||
precederCounts[edge.endVertex.getKey()] = precederCounts[edge.endVertex.getKey()] + 1;
|
||||
});
|
||||
|
||||
graph.getAllVertices().forEach((vertex) => {
|
||||
priorityQueue.add(vertex, precederCounts[vertex.getKey()]);
|
||||
});
|
||||
|
||||
while (!priorityQueue.isEmpty()) {
|
||||
const vertex = priorityQueue.poll();
|
||||
|
||||
sortedStack.push(vertex);
|
||||
vertex.getEdges().forEach((edge) => {
|
||||
// Decrease counter for all child nodes.
|
||||
precederCounts[edge.endVertex.getKey()] = precederCounts[edge.endVertex.getKey()] - 1;
|
||||
|
||||
// Update the information in priority queue.
|
||||
priorityQueue.changePriority(edge.endVertex, precederCounts[edge.endVertex.getKey()]);
|
||||
});
|
||||
}
|
||||
|
||||
return sortedStack;
|
||||
}
|
Loading…
Reference in New Issue
Block a user