图
图是网络结构抽象模型。图是一组由边连接的节点(或顶点)。
一个图G = (V,E)由以下元素组成。
- V:一组顶点
- E:一组边,连接V中的顶点
由一条边连接在一起的顶点称为相邻顶点。一个顶底的度是其相邻顶点的数量。
简单路径要求不包含重复的顶点。
如果图中每两个定点间在双向上都存在路径,则该图是强连通。
图可以是未加权的或是加权的。加权图的边被赋予了权值。
从数据结构的角度来说,有多种方式来表示图。在所有的表示法中,不存在绝对正确的方式。图的正确表示法取决于待解决的问题和图的类型。
- 邻接矩阵
- 邻接表
- 关联矩阵
//邻接表方式实现
class Graph{
constructor(){
this.vertices = []
this.adjList = new Dictionary()//见实现字典类
}
}
Graph.prototype.addVertex = function(v){
this.vertices.push(v)
this.adjList.set(v,[])
}
Graph.prototype.addEdge = function(v,w){
this.adjList.get(v).push(w)
this.adjList.get(w).push(v)
}
Graph.prototype.toString = function(){
let str = ''
for(let i = 0;i < this.vertices.length;i++){
str += vertices[i] + '->'
var neighbors = this.adjList.get(vertices[i])
for(let j = 0;j < neighbors.length;j++){
str += neighbors[j] + ' '
}
str += '\n'
}
return str
}
// 运行代码
let graph = new Graph()
let myVertices = ['A','B','C','D','E','F','G','H']
for(let i = 0;i < myVertices.length;i++){
graph.addVertex(myVertices[i])
}
graph.addEdge('A','B')
graph.addEdge('A','C')
graph.addEdge('A','D')
graph.addEdge('C','D')
graph.addEdge('C','G')
graph.addEdge('D','G')
graph.addEdge('D','H')
graph.addEdge('B','E')
graph.addEdge('B','F')
console.log(graph.toString())
// A -> B C D
// B -> A E F
// C -> A D G
// D -> A C G H
// E -> B
// F -> B
// G -> C D
// H -> D
有两种算法可以对图进行遍历:广度优先搜索(Breadth-First Search,BFS)和深度优先搜索(Depth-First Search,DFS)。
广度优先搜索算法和深度优先搜索算法基本上是相同的,只有一点不同,就是待访问顶点列表的数据结构。
| 算法 | 数据结构 | 描述 |
| 深度优先搜索 | 栈 | 通过将顶点存入栈中,顶点是沿着路径被探索的,存在新的相邻顶点就去访问。 |
| 广度优先搜索 | 队列 | 通过将顶点存入队列中,最先入队列的顶点先被探索。 |
当要标注已经访问过的顶点时,用三种颜色来反映它们的状态。
- 白色:表示该顶点还没有被访问。
- 灰色:表示该顶点被访问过,但并未被探索过。
- 黑色:表示该顶点被访问过且被完全探索过。
Graph.prototype.initColor = function(){
let color = []
for(let i = 0;i < this.vertices.length;i++){
color[this.vertices[i]] = 'white'
}
return color
}
Graph.prototype.bfs = function(v,cb){
let color = this.initColor()
let queue = new Queue(v)
while(!queue.isEmpty()){
let u = queue.dequeue()
let neighbors = this.adjList.get(u)
color[u] = 'gray'
for(let i = 0;i < neighbors.length;i++){
let item = neighbors[i]
if(color[item] == 'white'){
color[item] = 'gray'
queue.enqueue(item)
}
}
color[u] = 'black'
if(cb){
cb(u)
}
}
}
Graph.prototype.dfs = function(cb){
let color = this.initColor()
for(let i = 0;i < this.vertices.length;i++){
if(color[this.vertices[i]] == 'white'){
dfsVisit(vertices[i],color,cb)
}
}
function dfsVisit(u,color,cb){
color[u] = 'grey'
let neighbors = thia.adjList.get(u)
for(let i = 0;i < neighbors.length;i++){
let item = neighbors[i]
if(color[item] == 'white'){
dfsVisit(item,color,cb)
}
}
color[u] = 'black'
if(cb){
cb(u)
}
}
}
最短路径问题
未完待续...
以自己现在的努力程度,还没有资格和别人拼天赋

浙公网安备 33010602011771号