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

		//队列
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. 极验(geetest)验证码

    最近在做项目的时候,需要用到登录验证,在网上看到了一个很不错的验证插件,在此记录一下使用流程. 极限验证码   官网:http://www.geetest.com/,到GitHub下载服务端代码htt ...

  2. python金融与量化分析------Matplotlib(绘图和可视化)

    -----------------------------------------------------------Matplotlib:绘图和可视化------------------------ ...

  3. Glusterfs挂载报错解决办法

    环境查看 挂载glusterfs时候报错 下载软件(Redhat没有注册无法直接yum安装) https://buildlogs.centos.org/centos/6/storage/x86_64/ ...

  4. System.InvalidOperationException: 此实现不是 Windows 平台 FIPS 验证的加密算法的一部分。

    x 昨天还好好地,然后清理一下电脑垃圾,就突然报这个错误了; 网上搜索了一下:找到解决方案了,但是由于底层知识的功力不够,至今未知具体怎么导致的... 解决方案↓ 进注册表 按Win+R运行reged ...

  5. 淘宝NPM镜像cnpm

    # 安装cnpm命令 npm install -g cnpm --registry=https://registry.npm.taobao.org2.cnpm install

  6. synchronized 同步代码块,售票问题

    package cn.ljs.FristSync; public class SalerDemo extends Thread { static int tickets = 1000; String ...

  7. 从一条巨慢SQL看基于Oracle的SQL优化(重磅彩蛋+PPT)

    本文根据DBAplus社群第110期线上分享整理而成,文末还有好书送哦~ 讲师介绍 丁俊 新炬网络首席性能优化专家 SQL审核产品经理 DBAplus社群联合发起人.<剑破冰山-Oracle开发 ...

  8. MySQL命令:增删与改

    首先是对数据库的修改: --删除一个叫bbb111的数据库 DROP DATABASE bbb111; 对某数据库里一个表的修改: 重命名一张表 -- 三种效果一样的形式 RENAME TABLE 原 ...

  9. Linux下TCP/socket编程

    写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文! 本博客全网唯一合法URL:ht ...

  10. [linux] 对一个虚拟机的研究

    今天拿到了一个vmware的虚拟机硬盘镜像,是其他公司的演示产品. 启动之后是带着ubuntu字样的grub.进入系统之后也不是shell,而是一个定制的命令行.所以如果想了解细节的话,只能单独挂硬盘 ...