var Queue = function(){
var items = []
//队-存
// var item = function(name,priority){
// this.name = name
// this.priority = priority
// }
this.enqueue=(elment)=>{
items.push(elment)
}
//队-出
this.dequeue=()=>{
return items.shift()
}
//判断是否为空
this.isEmpty=()=>{
return !items.length
}
this.size=()=>{
return items.length
}
this.getitem=()=>{
return items
}
}
// 栈
var Stack = function(){
var items = []
this.push=(element)=>{
items.push(element)
}
this.pop=()=>{
return items.pop()
}
this.isEmpty=()=>{
return !items.length>0
}
this.size=()=>{
return items.length
}
this.getitem=()=>{
return items
}
}
// 图遍历:广度优先和深度优先
// 广度遍历图的横向 采用队的思想
// 深度遍历图的纵向 采用递归栈的思想
// 图的遍历基本思路
// 每一个节点有三种状态
// 1.未发现 (尚未发现此节点)
// 2.已经发现 (发现其他节点连接到此,但未查找节点全部连接的节点)
// 3.已经探索 (已经发现此节点连接的全部节点)
var Graph = function(){
// 图的定点
var vertices = []
// 图的边
var adjList = {}
// 添加图的定点 并且设置每个点对应的边为空
this.addVertex = function(v){
vertices.push(v)
adjList[v]=[]
}
this.addEdge = function(a,b){
// 无向连接 添加对应的各各顶点
adjList[a].push(b)
adjList[b].push(a)
}
// 打印邻接表
this.print = function(){
var s = '\n'
for(var i=0;i<vertices.length;i++){
var dindian = vertices[i]
s+=dindian + '=>'
var bian = adjList[dindian]
for(var j=0;j<bian.length;j++){
s+=bian[j]
}
s += '\n'
}
console.log(s)
}
// white 未发现
// grey 已发现未探索
// black 已探索
var initColor = function(){
var color = {}
for(var i=0;i<vertices.length;i++){
color[vertices[i]]='white'
}
return color
}
// 广度遍历图
this.bfsd = function(v,callback){
var color = initColor()
/*
color= {
'A':'white',
'B':white
}
*/
var queue = new Queue()
queue.enqueue(v)
while(!queue.isEmpty()){
var now = queue.dequeue()
var bian = adjList[now]
for(var i=0;i<bian.length;i++){
var w = bian[i]
if(color[w]=='white'){
// 未发现的全部入列 并且标识为已发现
color[w]='grey'
queue.enqueue(w)
}
}
color[now]='black'
if(callback){
callback(now)
}
}
}
// 广度遍历图 得到点的距离,以及对应的回溯点
this.BFS = function(v,callback){
var color = initColor()
/*
color= {
'A':'white',
'B':white
}
*/
var queue = new Queue()
queue.enqueue(v)
var d = {}//距离
var pred = {} //回溯点
for(var i=0;i<vertices.length;i++){
d[vertices[i]]=0
pred[vertices[i]]=null
}
while(!queue.isEmpty()){
var now = queue.dequeue()
var bian = adjList[now]
for(var i=0;i<bian.length;i++){
var w = bian[i]
if(color[w]=='white'){
// 未发现的全部入列 并且标识为已发现
color[w]='grey'
// 设置回溯点
pred[w] = now
d[w]=d[now]+1
queue.enqueue(w)
}
}
color[now]='black'
if(callback){
callback(now)
}
}
return {
pred,
d
}
}
}
var g = new Graph()
g.addVertex('A')
g.addVertex('B')
g.addVertex('C')
g.addVertex('D')
g.addVertex('E')
g.addVertex('F')
g.addEdge('A','B')
g.addEdge('A','C')
g.addEdge('A','D')
g.addEdge('C','D')
g.addEdge('B','E')
g.addEdge('F','B')
g.addEdge('D','F')
// g.bfsd('A',function(e){console.log(e)})
// var s = g.
console.log()
var s = g.BFS('A')
// 求出最短路径
var zuiduan = function(from,to){
var v = to
var path = new Stack()
while(v!=from){
// console.log(v)
path.push(v)
v=s.pred[v]
}
path.push(v)
var str = ''
while(!path.isEmpty()){
str += path.pop()+'-'
}
str = str.slice(0,str.length-1)
console.log(str)
}
zuiduan('A','F')