forked from zhoutk/js-data-struct
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgraph.js
137 lines (126 loc) · 3.77 KB
/
graph.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/***************************************************************************
> File Name : graph.js
> Author : zhoutk
> Mail : zhoutk@189.cn
> Create Time : 2015-10-01 08:56
***************************************************************************/
(function(){
"use strict";
function Graph(v){
this.vertexs = v;
this.vertexList = [];
this.edges = 0;
this.adj = Object.create(null);
this._vertex_marked = [];
this._edgeTo = []; //保存可达路径
}
//拓扑排序
Graph.prototype.topSort = function(){
var stack = [];
var visited = [];
for(var i =0; i < this.vertexs; i++){
visited[i] = false;
}
for(var i = 0; i < this.vertexs; i++){
if(visited[i] == false){
this.topSortHelper(i, visited, stack);
}
}
var al = stack.pop();
while(al != null){
console.log(this.vertexList[al]);
al = stack.pop();
}
};
Graph.prototype.topSortHelper = function(v, visited, stack){
visited[v] = true;
for(var w in this.adj[v]){
if(!visited[this.adj[v][w]]){
this.topSortHelper(this.adj[v][w], visited, stack);
}
}
stack.push(v);
};
Graph.prototype.initMarked = function(){
for(var i = 0; i< this.vertexs; i++){
this._vertex_marked[i] = false;
}
};
Graph.prototype.pathTo = function(v){
var start = 0;
this.bfs(start);
if(!this.hasPathTo(v)){
return null;
}
var path = [];
for(var i = v; i != start; i = this._edgeTo[i]){
path.push(i);
}
path.push(start);
var rs = "";
while(path.length > 0){
if(path.length > 1){
rs += path.pop() + "-";
}
else{
rs += path.pop();
}
}
return rs;
};
Graph.prototype.hasPathTo = function(v){
return this._vertex_marked[v];
};
//广度优化遍历,并生成可达路径,为计算无权最短路径提供数据
Graph.prototype.bfs = function(v){
this.initMarked();
var queue = [];
this._vertex_marked[v] = true;
queue.push(v);
while(queue.length > 0){
var cur = queue.shift();
console.log("Visited vertex: " + cur);
for(var w in this.adj[cur]){
if(!this._vertex_marked[this.adj[cur][w]]) {
this._edgeTo[this.adj[cur][w]] = cur;
this._vertex_marked[this.adj[cur][w]] = true;
queue.push(this.adj[cur][w]);
}
}
}
};
//深度优先遍历
Graph.prototype.dfs = function(v){
if(arguments[1] == undefined){
this.initMarked();
}
this._vertex_marked[v] = true;
console.log("Visited vertex: " + v);
for(var w in this.adj[v]){
if(!this._vertex_marked[this.adj[v][w]]){
this.dfs(this.adj[v][w],1);
}
}
};
Graph.prototype.display = function(){
for(var i = 0; i < this.vertexs; i++){
if(this.adj[i] == null){
console.log(i + " --> This vertex is isolate.")
}else{
console.log(i + " --> " + this.adj[i].join(" "))
}
}
};
Graph.prototype.addEdge = function(v, w){
if(this.adj[v] == null){
this.adj[v] = [];
}
this.adj[v].push(w);
if(this.adj[w] == null){
this.adj[w] = [];
}
this.adj[w].push(v);
this.edges++;
};
module.exports = Graph;
})();