mirror of
https://github.com/linghuam/boutique-books.git
synced 2024-11-24 18:44:57 +00:00
graph
This commit is contained in:
parent
78b2cfce3a
commit
47b8b209f3
102
b00-阅读笔记/学习js数据结构与算法/graph.js
Normal file
102
b00-阅读笔记/学习js数据结构与算法/graph.js
Normal file
@ -0,0 +1,102 @@
|
||||
function Graph() {
|
||||
this.vertices = [];
|
||||
this.vertexMap = new Map();
|
||||
this.adjList = new Map();
|
||||
this.addVertex = function(v) {
|
||||
return this.vertexMap.has(v.id) ? null : (v.status = 0, this.vertexMap.set(v.id, v), this.vertices.push(v),this.adjList.set(v.id, new Set()), v);
|
||||
};
|
||||
this.addEdge = function(sourceId, targetId) {
|
||||
if (this.vertexMap.has(sourceId) && this.vertexMap.has(targetId)) {
|
||||
this.adjList.get(sourceId).add(this.vertexMap.get(targetId));
|
||||
this.adjList.get(targetId).add(this.vertexMap.get(sourceId));
|
||||
}
|
||||
return this;
|
||||
};
|
||||
this.getVertex = function(id) {
|
||||
return this.vertexMap.get(id);
|
||||
};
|
||||
this.getVertexAdj = function(id) {
|
||||
return this.adjList.get(id) || [];
|
||||
};
|
||||
this.toString = function() {
|
||||
this.adjList.forEach((value, key) => {
|
||||
console.log(key + ':' + Array.from(value).map(e => e.id).join(',') + '\n');
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function BFS(graph, root, callback) {
|
||||
var queue = [];
|
||||
if (root == null) return null;
|
||||
root.status = 1 && queue.push(root);
|
||||
while(queue.length) {
|
||||
var curVertex = queue.shift();
|
||||
// 将相邻节点入队
|
||||
var adjVertexs = graph.getVertexAdj(curVertex.id);
|
||||
adjVertexs.forEach(e => {
|
||||
// 忽略已经入队或已经被访问过的节点
|
||||
if (e.status === 0) {
|
||||
e.status = 1 && queue.push(e);
|
||||
}
|
||||
});
|
||||
// 节点被访问
|
||||
callback(curVertex);
|
||||
curVertex.status = 2;
|
||||
}
|
||||
}
|
||||
|
||||
function DFS(graph, callback) {
|
||||
var stack = [];
|
||||
var vertexs = graph.vertices;
|
||||
// 遍历每个节点,若节点未被访问,则入栈
|
||||
// 若栈非空,出栈
|
||||
// 继续遍历其相邻未被访问的子节点
|
||||
for (var i = 0, length = vertexs.length; i < length; i++) {
|
||||
if (vertexs[i].status === 0) {
|
||||
vertexs[i].status = 1;
|
||||
stack.push(vertexs[i]);
|
||||
while(stack.length) {
|
||||
var v = stack.pop();
|
||||
v.status = 2;
|
||||
callback(v);
|
||||
var adjVertexs = graph.getVertexAdj(v.id);
|
||||
adjVertexs.forEach(e => {
|
||||
if (e.status === 0) {
|
||||
e.status = 1;
|
||||
stack.push(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var graph = new Graph();
|
||||
graph.addVertex({id: 'A'});
|
||||
graph.addVertex({id: 'B'});
|
||||
graph.addVertex({id: 'C'});
|
||||
graph.addVertex({id: 'D'});
|
||||
graph.addVertex({id: 'E'});
|
||||
graph.addVertex({id: 'F'});
|
||||
graph.addVertex({id: 'G'});
|
||||
graph.addVertex({id: 'H'});
|
||||
graph.addVertex({id: 'I'});
|
||||
graph.addEdge('A', 'B');
|
||||
graph.addEdge('A', 'C');
|
||||
graph.addEdge('A', 'D');
|
||||
graph.addEdge('B', 'E');
|
||||
graph.addEdge('B', 'F');
|
||||
graph.addEdge('C', 'D');
|
||||
graph.addEdge('C', 'G');
|
||||
graph.addEdge('D', 'G');
|
||||
graph.addEdge('D', 'H');
|
||||
graph.addEdge('E', 'I');
|
||||
|
||||
// console.log('BFS:\n');
|
||||
// BFS(graph, graph.getVertex('A'), e => {
|
||||
// console.log(e.id);
|
||||
// });
|
||||
console.log('DFS:\n');
|
||||
DFS(graph, e => {
|
||||
console.log(e.id);
|
||||
});
|
13
b00-阅读笔记/学习js数据结构与算法/index.html
Normal file
13
b00-阅读笔记/学习js数据结构与算法/index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>test</title>
|
||||
<script src="./graph.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -388,7 +388,7 @@ function Graph() {
|
||||
this.vertexMap = new Map();
|
||||
this.adjList = new Map();
|
||||
this.addVertex = function(v) {
|
||||
return this.vertexMap.has(v.id) ? null : (this.vertexMap.set(v.id, v),this.vertices.push(v),this.adjList.set(v.id, new Set()), v);
|
||||
return this.vertexMap.has(v.id) ? null : (v.status = 0, this.vertexMap.set(v.id, v), this.vertices.push(v),this.adjList.set(v.id, new Set()), v);
|
||||
};
|
||||
this.addEdge = function(sourceId, targetId) {
|
||||
if (this.vertexMap.has(sourceId) && this.vertexMap.has(targetId)) {
|
||||
@ -397,6 +397,12 @@ function Graph() {
|
||||
}
|
||||
return this;
|
||||
};
|
||||
this.getVertex = function(id) {
|
||||
return this.vertexMap.get(id);
|
||||
};
|
||||
this.getVertexAdj = function(id) {
|
||||
return this.adjList.get(id) || [];
|
||||
};
|
||||
this.toString = function() {
|
||||
this.adjList.forEach((value, key) => {
|
||||
console.log(key + ':' + Array.from(value).map(e => e.id).join(',') + '\n');
|
||||
@ -407,8 +413,50 @@ function Graph() {
|
||||
|
||||
### 图的遍历
|
||||
|
||||
* 广度优先(BFS):用**栈**实现。
|
||||
* 深度优先(DFS):用**队列**实现
|
||||
* 广度优先(BFS):用**队列**实现。
|
||||
* 深度优先(DFS):用**栈**实现。
|
||||
|
||||
用 status 表示节点状态:
|
||||
|
||||
* 0 - 初始状态
|
||||
* 1 - 被探索状态
|
||||
* 2 - 被访问过状态
|
||||
|
||||
```js
|
||||
// 广度优先(BFS)算法:用**队列**实现。
|
||||
/*
|
||||
1. 创建一个队列 Q
|
||||
2. 将 v 标记为 1,并入队
|
||||
3. 如果 Q 非空,重复以下步骤
|
||||
3.1 将 u 出队
|
||||
3.2 寻找 u 的相邻节点,并将未被访问的节点入栈,并标记为 1
|
||||
3.3 访问节点,标记为 2
|
||||
*/
|
||||
function BFS(root, callback) {
|
||||
var queue = [];
|
||||
if (root == null) return null;
|
||||
root.status = 1 && queue.push(root);
|
||||
while(queue.length) {
|
||||
var curVertex = queue.shift();
|
||||
// 将相邻节点入队
|
||||
var adjVertexs = graph.getVertexAdj(curVertex.id);
|
||||
adjVertexs.forEach(e => {
|
||||
// 忽略已经入队或已经被访问过的节点
|
||||
if (e.status === 0) {
|
||||
e.status = 1 && queue.push(e);
|
||||
}
|
||||
});
|
||||
// 节点被访问
|
||||
callback(curVertex);
|
||||
curVertex.status = 2;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
// 深度优先(DFS)算法:用**栈**实现。
|
||||
function DFS(callback) {}
|
||||
```
|
||||
|
||||
## 排序和搜索算法
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user