图的实现
function Graph(v) {
this.vertices = v;
this.vertexList = [];
this.edges = 0;
this.adj = [];
for (var i = 0; i < this.vertices; ++i) {
this.adj[i] = [];
this.adj[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.pathTo = pathTo;
this.topSortHelper = topSortHelper;
this.topSort = topSort;
}
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);
}
function addEdge(v,w) {
this.adj[v].push(w);
this.adj[w].push(v);
this.edges++;
}
/*function showGraph() {
for (var i = 0; i < this.vertices; ++i) {
putstr(i + " -> ");
for (var j = 0; j < this.vertices; ++j) {
if (this.adj[i][j] != undefined)
putstr(this.adj[i][j] + ' ');
}
print();
}
}*/
// a new function to display symbolic names instead of numbers
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;
}
// 深度优先测试用例
g = new Graph(5);
g.addEdge(0,1);
g.addEdge(0,2);
g.addEdge(1,3);
g.addEdge(2,4);
g.showGraph();
g.dfs(0);
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
138
139
140
141
142
143
144
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
138
139
140
141
142
143
144
← 二叉树