mirror of
https://github.com/linghuam/boutique-books.git
synced 2024-11-22 01:24: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.vertexMap = new Map();
|
||||||
this.adjList = new Map();
|
this.adjList = new Map();
|
||||||
this.addVertex = function(v) {
|
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) {
|
this.addEdge = function(sourceId, targetId) {
|
||||||
if (this.vertexMap.has(sourceId) && this.vertexMap.has(targetId)) {
|
if (this.vertexMap.has(sourceId) && this.vertexMap.has(targetId)) {
|
||||||
@ -397,6 +397,12 @@ function Graph() {
|
|||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
this.getVertex = function(id) {
|
||||||
|
return this.vertexMap.get(id);
|
||||||
|
};
|
||||||
|
this.getVertexAdj = function(id) {
|
||||||
|
return this.adjList.get(id) || [];
|
||||||
|
};
|
||||||
this.toString = function() {
|
this.toString = function() {
|
||||||
this.adjList.forEach((value, key) => {
|
this.adjList.forEach((value, key) => {
|
||||||
console.log(key + ':' + Array.from(value).map(e => e.id).join(',') + '\n');
|
console.log(key + ':' + Array.from(value).map(e => e.id).join(',') + '\n');
|
||||||
@ -407,8 +413,50 @@ function Graph() {
|
|||||||
|
|
||||||
### 图的遍历
|
### 图的遍历
|
||||||
|
|
||||||
* 广度优先(BFS):用**栈**实现。
|
* 广度优先(BFS):用**队列**实现。
|
||||||
* 深度优先(DFS):用**队列**实现
|
* 深度优先(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