JavaScript 拓扑排序 算法

拓扑排序会对有向图的所有顶点进行排序,使有向边从前面的顶点指向后面的顶点。

拓扑排序算法与深度优先搜索类似。不同的是,拓扑排序算法不会立即输出已访问的顶点,而是访问当前顶点邻接表中的所有相邻顶点,直到这个列表穷尽时,才将当前顶点压入栈中。

拓扑排序算法被拆分为两个函数。第一个函数 topSort(),会设置排序进程并调用一个辅助函数 topSortHelper(),然后显示排序好的顶点列表。

主要工作是在递归函数 topSortHelper() 中完成的。这个函数会将当前顶点标记为已访问,然后递归访问当前顶点邻接表中的每个相邻顶点,标记这些顶点为已访问。最后,将当前顶点压入栈。

function topSort() {
	var stack = [];
	var visited = [];
	for (var i = 0; i < this.vertices; i++) {
		visited[i] = false;
	}
	for (var i = 0; i < this.vertices; i++) {
		if (visited[i] == false) {
			this.topSortHelper(i, visited, stack);
		}
	}
	for (var i = 0; i < stack.length; i++) {
		if (stack[i] != undefined && stack[i] != false) {
			print(this.vertexList[stack[i]]);
		}
	}
}


function topSortHelper(v, visited, stack) {
	visited[v] = true;
	for each(var w in this.adj[v]) {
		if (!visited[w]) {
			this.topSortHelper(visited[w], visited, stack);
		}
	}
	stack.push(v);
}

Graph 类也将被修改,这样不仅可以用于数字顶点,还可以用于符号顶点。在代码中,每个顶点都只仍标注了数字,但是我们添加了一个 vertexList 数组,将各个顶点关联到一个符号

Graph 类

function Graph(v) {
	this.vertices = v;
	this.vertexList = [];
	this.edges = 0;
	this.adj = [];
	for (var i = 0; i < this.vertices; ++i) {
		图和图算法| 139
		this.adj[i] = [];
		this.ajd[i].push("");
	}
	this.addEdge = addEdge;
	this.showGraph = showGraph;
	this.dfs = dfs;
	this.marked = [];
	for (var i = 0; i < this.vertices; ++i) {
		this.marked[i] = false;
	}
	this.bfs = bfs;
	this.edgeTo = [];
	this.hasPathTo = hasPathTo;
	this.topSortHelper = topSortHelper;
	this.topSort = topSort;
}


function topSort() {
	var statck = [];
	var visited = [];
	for (var i = 0; i < this.vertices; i++) {
		visited[i] = false;
	}
	for (var i = 0; i < stack.length; i++) {
		if (visited[i] == false) {
			this.topSortHelper(i, visited, stack);
		}
	}
	for (var i = 0; i < stack.length; i++) {
		if (stack[i] != undefined && stack[i] != false) {
			print(this.vertexList[stack[i]]);
		}
	}
}
function topSortHelper(v, visited, stack) {
	visited[v] = true;
	for each(var w in this.adj[v]) {
		if (!visited[w]) {
			this.topSortHelper(visited[w], visited, stack);
		}
	}
	stack.push(v);
}

function addEdge(v, w) {
	this.adj[v].push(w);
	this.adj[w].push(v);
	this.edges++;
}
function showGraph() {
	var visited = [];
	for (var i = 0; i < this.vertices; ++i) {
		putstr(this.vertexList[i] + " -> ");
		visited.push(this.vertexList[i]);
		for (var j = 0; j < this.vertices; ++j) {
			if (this.adj[i][j] != undefined) {
				if (visited.indexOf(this.vertexList[j]) < 0) {
					putstr(this.vertexList[j] + ' ');
				}
			}
		}
		print();
		visited.pop();
	}
}

function dfs(v) {
	this.marked[v] = true;
	if (this.adj[v] != undefined) {
		print("Visited vertex: " + v);
	}
	for each(var w in this.adj[v]) {
		if (this.marked[w]) {
			this.dfs(w);
		}
	}
}

function bfs(s) {
	var queue = [];
	this.marked[s] = true;
	queue.unshift(s);
	while (queue.length > 0) {
		var v = queue.shift();
		if (typeof(v) != 'string') {
			print("Visited vertex:" + v);
		}
		for each(var w in this.adj[v]) {
			if (!this.marked[w]) {
				this.edgeTo[w] = v;
				this.marked[w] = true;
				queue.unshift(w);
			}
		}
	}
}

function hasPathTo(v) {
	return this.marked[v];
}

function pathTo(v) {
	var source = 0;
	if (!this.hasPathTo(v)) {
		return undefined;
	}
	var path = [];
	for (var i = v; i != source; i = this.edgeTo[i]) {
		path.push(i);
	}
	path.push(s);
	return path;
}

load("Graph.js");
g = new Graph(6);
g.addEdge(1, 2);
g.addEdge(2, 5);
g.addEdge(1, 3);
g.addEdge(1, 4);
g.addEdge(0, 1);
g.vertexList = ["CS1", "CS2", "Data Structures",
	"Assembly Language", "Operating Systems",
	"Algorithms"
];
g.showGraph();
g.topSort();
以上代码的输出结果为:
CS1
CS2
Data Structures
Assembly Language
Operating Systems
Algorithms


你可能感兴趣的:(前端基础,JavaScript)