//邻居连表
//先加入各顶点,然后加入边

		//队列
var Queue = (function(){
var item = new WeakMap();
class Queue{
constructor(){
item.set(this,[]);
}
enqueue(ele){
var ls = item.get(this);
ls.push(ele);
}
dequeue(){
var ls = item.get(this);
return ls.shift();
}
size(){
var ls = item.get(this);
return ls.length;
}
front(){
var ls = item.get(this);
return ls[0];
}
isEmpty(){
var ls = item.get(this);
return !ls.length;
}
print(){
var ls = item.get(this); for(var i = 0; i < ls.length; i++){
console.log(`${ls[i]}`);
}
}
}
return Queue;
})(); //深度优先搜索 //广度优先搜索
function Graph(){
var vertices = []; //存储所有的顶点
var adjList = {}; //存储所有顶点的相邻顶点 this.addVertex = function(v){
if(!adjList[v]){
vertices.push(v);
adjList[v] = [];
}else{
throw new Error("该顶点已经存在");
}
};
var initializeColor = function(){
var color = {};
for(var i = 0; i < vertices.length; i++){
color[vertices[i]] = 'white';
}
return color;
} this.addEdge = function(v,w){
if(adjList[v] && adjList[w]){
adjList[v].push(w);
adjList[w].push(v); }else{
throw new Error("链接不存在的顶点");
}
};
this.toString = function(){
var s = '';
for (var i=0; i<vertices.length; i++){ //{10}
s += vertices[i] + ' -> ';
var neighbors = adjList[vertices[i]]; //{11}
for (var j=0; j<neighbors.length; j++){ //{12}
s += neighbors[j] + ' ';
}
s += '\n'; //{13}
}
return s;
};
this.print = function(){
console.log(this.toString());
}; //广度优先搜索,寻找每个点
//搜索每个点的相邻点
//1、初始化,所有的顶点状态为 white,即没有遍历到
//2、通过该点,拿到相邻点的数组,遍历相邻点
//3、如果相邻点是white,则变灰(表示发现该节点)。并加入队列
//4、当相邻的都遍历完成,将自己变成黑色(表示已经探索完成该节点),进入队列下一次的循环 this.bfs = function(v,callback){
var color = initializeColor();
queue = new Queue();
queue.enqueue(v);
while(!queue.isEmpty()){
var u = queue.dequeue();
neighbors = adjList[u];
color[u] = 'grey';
for(var i = 0; i < neighbors.length; i++){
var w = neighbors[i];
if(color[w] === 'white'){
color[w] = 'grey';
queue.enqueue(w);
}
}
color[u] = "black";
if(callback){
callback(u);
}
}
}; //广度优先算法,计算每个顶点的距离
this.BFS = function(v){
var color = initializeColor();
queue = new Queue();
queue.enqueue(v);
d = []; //距离列表
pred = []; //前溯点
for (var i=0; i<vertices.length; i++){
d[vertices[i]] = 0;
pred[vertices[i]] = null;
}
while(!queue.isEmpty()){
var u = queue.dequeue();
neighbors = adjList[u];
color[u] = 'grey';
for(var i = 0; i < neighbors.length; i++){
var w = neighbors[i];
if(color[w] === 'white'){
color[w] = 'grey';
d[w] = d[u] + 1;
pred[w] = u;
queue.enqueue(w);
}
}
color[u] = "black"; }
return {
distances: d,
predecessors: pred
}
} this.getPath = function(u){
//打印最短路径
//回溯之前的相邻点
var shortestPath = this.BFS(u);
var fromVertex = vertices[0];
for (var i=1; i<vertices.length; i++){ var toVertex = vertices[i],
path = [];
for (var v=toVertex; v!== fromVertex;
v=shortestPath.predecessors[v]) {
path.push(v);
}
path.push(fromVertex);
var s = path.join("-"); console.log(s);
}
} //深度优先算法
this.dfs = function(callback){
var color = initializeColor();
for(var i = 0; i < vertices.length; i++){
if(color[vertices[i]] === 'white'){
dfsVisit(vertices[i], color, callback);
}
}
}
function dfsVisit(u,color,callback){
color[u] = 'grey';
if(callback){
callback(u);
}
var neighbors = adjList[u];
for(var i = 0; i < neighbors.length; i++){
var w = neighbors[i];
if(color[w] === 'white'){
dfsVisit(w,color,callback)
}
}
color[u] = "black";
} //深度搜索,发现时间(标记为灰色)和完成探索时间(标记为黑色)
//将发现时间倒序排列,即可得到拓扑图
var time = 0;
this.DFS = function(){
var color = initializeColor(),
d = [],
f = [],
p = [],
time = 0;
for(var i = 0; i < vertices.length; i++){
f[vertices[i]] = 0;
d[vertices[i]] = 0;
p[vertices[i]] = null;
}
for(var i = 0; i < vertices.length; i++){
if(color[vertices[i]] === 'white'){
DFSVisit(vertices[i],color,d,f,p);
}
}
return {
discovery:d,
finished:f,
predecessors:p
}
}
function DFSVisit(u,color,d,f,p){
console.log("discovered" + u);
color[u] = 'grey';
d[u] = ++time;
var neighbors = adjList[u];
for(var i = 0; i < neighbors.length; i++){
var w = neighbors[i];
if(color[w] === 'white'){
p[w] = u;
DFSVisit(w,color,d,f,p);
}
} color[u] = 'block';
f[u] = ++time;
console.log("explored"+u);
} } var graph = new Graph();
var myVertices = ['A','B','C','D','E','F','G','H','I']; //{7}
for (var i=0; i<myVertices.length; i++){ //{8}
graph.addVertex(myVertices[i]);
}
graph.addEdge('A', 'B'); //{9}
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');
graph.addEdge('E', 'I'); /*
graph.bfs("A",function(cnode){
console.log(cnode);
})
console.log(graph.BFS("A"));
graph.getPath('A'); graph.dfs(function(cnode){
console.log(cnode);
});*/ console.log(graph.DFS()); /*
如果要计算加权图中的最短路径(例如城市之间最短距离)广度优先搜索未必合适。
* Dijkstra算法解决了单源最短路径问题。 Bellman-Ford算法解决了边权值为负的
单源最短路径问题。 A*搜索算法解决了求仅一对顶点间的最短路径问题,它用经验法则来加速搜
索过程。 Floyd-Warshall算法解决了求所有顶点对间的最短路径这一问题。
*
* */

  

js图的数据结构处理----邻链表,广度优先搜索,最小路径,深度优先搜索,探索时间拓扑的更多相关文章

  1. (转)广度优先搜索BFS和深度优先搜索DFS

    1. 广度优先搜索介绍 广度优先搜索算法(Breadth First Search),又称为"宽度优先搜索"或"横向优先搜索",简称BFS. 它的思想是:从图中 ...

  2. matlab练习程序(广度优先搜索BFS、深度优先搜索DFS)

    如此经典的算法竟一直没有单独的实现过,真是遗憾啊. 广度优先搜索在过去实现的二值图像连通区域标记和prim最小生成树算法时已经无意识的用到了,深度优先搜索倒是没用过. 这次单独的将两个算法实现出来,因 ...

  3. 利用广度优先搜索(BFS)与深度优先搜索(DFS)实现岛屿个数的问题(java)

    需要说明一点,要成功运行本贴代码,需要重新复制我第一篇随笔<简单的循环队列>代码(版本有更新). 进入今天的主题. 今天这篇文章主要探讨广度优先搜索(BFS)结合队列和深度优先搜索(DFS ...

  4. js图的数据结构处理---弗洛伊德算法

    function Graph() { this.graph = [ [0, 2, 4, 0, 0, 0], [0, 0, 1, 4, 2, 0], [0, 0, 0, 0, 3, 0], [0, 0, ...

  5. js图的数据结构处理---迪杰斯特拉算法

    /*//1.确定数据结构, mapf[i][j] 为点i到点j的距离 [ Infinity 2 5 Infinity Infinity Infinity Infinity 2 6 Infinity I ...

  6. js图的数据结构处理----普里姆算法

    //求加权无向连通图的MST的贪心算法 //最小树,最小路径联通各个点 function PRIM(){ var graph = [ [], [undefined,Infinity, 23 ,Infi ...

  7. 数据结构和算法总结(一):广度优先搜索BFS和深度优先搜索DFS

    前言 这几天复习图论算法,觉得BFS和DFS挺重要的,而且应用比较多,故记录一下. 广度优先搜索 有一个有向图如图a 图a 广度优先搜索的策略是: 从起始点开始遍历其邻接的节点,由此向外不断扩散. 1 ...

  8. 广度优先搜索(BFS)与深度优先搜索(DFS)的对比及优缺点

    深搜,顾名思义,是深入其中.直取结果的一种搜索方法. 如果深搜是一个人,那么他的性格一定倔得像头牛!他从一点出发去旅游,只朝着一个方向走,除非路断了,他绝不改变方向!除非四个方向全都不通或遇到终点,他 ...

  9. 深度优先搜索(DFS)与广度优先搜索(BFS)的Java实现

    1.基础部分 在图中实现最基本的操作之一就是搜索从一个指定顶点可以到达哪些顶点,比如从武汉出发的高铁可以到达哪些城市,一些城市可以直达,一些城市不能直达.现在有一份全国高铁模拟图,要从某个城市(顶点) ...

随机推荐

  1. centos7 安装redis服务及phpredis扩展

    闲话少说 服务器版本:centos7.6 64位 软件包:https://pan.baidu.com/s/1Gb4iz5mqLqNVWvvZdBiOMQ 提取码: xrhx 一.安装redis 放在/ ...

  2. AngularJS快速教程

    作者:arccosxy  转载请注明出处:http://www.cnblogs.com/arccosxy/ AngularJS是Google开源的一款JavaScript MVC前端框架,弥补了HTM ...

  3. elasticsearch与solr区别

    solr:优点1.Solr有一个更大.更成熟的用户.开发和贡献者社区.2.支持添加多种格式的索引,如:HTML.PDF.微软 Office 系列软件格式以及 JSON.XML.CSV 等纯文本格式.3 ...

  4. 泡泡一分钟:Stabilize an Unsupervised Feature Learning for LiDAR-based Place Recognition

    Stabilize an Unsupervised Feature Learning for LiDAR-based Place Recognition Peng Yin, Lingyun Xu, Z ...

  5. Robot Framework使用For循环

    1.普通的For循环 在一个普通的For循环中,循环开始的关键字是 :FOR ,其中的:用于与一般关键字做区分,对于循环结构体内的每一行,使用 \ 作为改行的行首关键字.对于循环中的变量,可以在 IN ...

  6. POJ 1063 - Flip and Shift

    Description This puzzle consists of a random sequence of m black disks and n white disks on an oval- ...

  7. [No000011C]使人醒悟的生活中的定律

    1.     墨菲定律 我们在事前应该是尽可能想得周到.全面一些,如果真的发生不幸或者损失,就笑着应对吧,关键在于总结所犯的错误,而不是企图掩盖它. 2.     羊群效应 对他人的信息不可全信也不可 ...

  8. English class 82 The Importance of traveling

    1,since I could basically walk : pretty much 2,Malaysian girl 3,profound love: deep very inportant 4 ...

  9. [性能优化] perf

    运行时性能分析工具 wiki:https://en.wikipedia.org/wiki/Perf_(Linux) linux wiki:https://perf.wiki.kernel.org/in ...

  10. 中位数&贪心

    谁能想到基本算法就这么难呢?我想去冲省选,但是迟迟在这些地方 花时间 算是提升自己的思维算了. 这道题呢 答案其实很简单每个数在a的位置和在b的位置之差的累加/2即是答案为什么呢?考虑当前数字 要向后 ...