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

		//队列
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. vscode 设置 cmder为终端

    "terminal.integrated.shell.windows": "cmd.exe", "terminal.integrated.shellA ...

  2. solus 系统 - 安装编译工具

    将会安装 gcc,make等工具 sudo eopkg install -c system.devel VirtualBox工具 https://solus-project.com/articles/ ...

  3. 评估分类器性能的度量,像混淆矩阵、ROC、AUC等

    评估分类器性能的度量,像混淆矩阵.ROC.AUC等 内容概要¶ 模型评估的目的及一般评估流程 分类准确率的用处及其限制 混淆矩阵(confusion matrix)是如何表示一个分类器的性能 混淆矩阵 ...

  4. 洛谷 P1181数列分段SectionI 【贪心】

    题目描述 对于给定的一个长度为NN的正整数数列A_iAi​,现要将其分成连续的若干段,并且每段和不超过MM(可以等于MM),问最少能将其分成多少段使得满足要求. 输入输出格式 输入格式: 第1行包含两 ...

  5. echarts pie 图表 显示的label 中内容 字体大小自定义

    option = { tooltip: { trigger: 'item', formatter: "{a} <br/>{b}: {c} ({d}%)" }, lege ...

  6. [No0000EE]主要的宏观经济指标查询

    主要的宏观经济指标查询 国内:东财>经济数据 _ 数据中心:http://data.eastmoney.com/center/macro.html东财>经济数据 :http://data. ...

  7. 【libreOJ模板】并查集(输入挂,取模与find优化)

    1.了解了各种输入挂性orz,找到了一个合适的 2.find用while写能快一倍,并且能被数据卡掉 3.取模只能快十几毫秒,但也能被数据卡掉 取模find双优化是1997mm过的 再加一个性价比较高 ...

  8. spark运行wordcount程序

    首先提一下spark rdd的五大核心特性: 1.rdd由一系列的分片组成,比如说128m一片,类似于hadoop中的split2.每一个分区都有一个函数去迭代/运行/计算3.一系列的依赖,比如:rd ...

  9. Page3:组合系统状态空间输入输出描述、矩阵指数函数性质[Linear System Theory]

    内容包含组合系统的状态空间描述以及输入输出描述,零输入响应的概念以及矩阵指数函数的性质

  10. Fiddler怎么可以抓取https的请求包

    对于https的协议是带有安全的功能,所有有一些的https的协议是无法抓到的,所以需要通过设置filler中来对,来使用filler的方式的来抓取到https的请求包,那么如何使用filler中抓取 ...