1.图的表示方式
①邻接矩阵
邻接矩阵让每个节点和一个整数相关联,该整数作为数组的下标。用一个二维数组表示顶点之间的连接。在二维数组中,0表示无连接,1表示有连接。邻接矩阵的问题是如果图是个稀疏图,那么会浪费很多空间去存储大量无意义的0.
②邻接表
邻接表由图中每个顶点以及和顶点相邻的顶点列表组成。邻接表可以用map或者哈希表来表示。如图:
邻接表计算出度:直接看每个顶点后边相关的顶点数。
2.图的添加操作
//添加方法(邻接表)
//添加顶点
Graph.prototype.addVertex=function(v){
this.vertexes.push(v);
this.edges.set(v,[]);
}
//添加边
Graph.prototype.addEdge=function(v1,v2){
this.edges.get(v1).push(v2);
this.edges.get(v2).push(v1);
}
3.图的toString方法
//toString方法
Graph.prototype.toString=function(){
var res='';
for(var i=0;i<this.vertexes.length;i++){
res+=this.vertexes[i]+'->';
var vedge=this.edges.get(this.vertexes[i]);
for(var j=0;j<vedge.length;j++){
res+=vedge[j]+' ';
}
res+='\n';
}
return res;
}
4.图的遍历
图的遍历思想:每个顶点访问一次,并且不能有重复的访问。
图的遍历方法:广度优先搜素(BFS)以及深度优先搜索(DFS)。两种遍历算法都需要指定第一个访问的顶点。
广度优先搜素(BFS):
//初始化图的颜色,白色代表未被访问过,灰色代表被访问过但未探索过,黑色代表被访问过且被探索过
Graph.prototype.initColor=function(){
var color=[];
for(var i=0;i<this.vertexes.length;i++){
color[this.vertexes[i]]='white';
}
return color;
}
//广度优先搜索(BFS)
Graph.prototype.BFS=function(firstV,handle){
//1.初始化图的颜色
var color= this.initColor();
//2.创建一个数组
var array=new Array();
//3.将顶点加入到数组中
array.push(firstV);
//4.循环从数组中取出元素并加入相关元素
while(array.length!=0){
var v=array.shift();
var list=this.edges.get(v);
color[v]='grey';
for(var i=0;i<list.length;i++){
var e=list[i];
if(color[e]=='white'){
array.push(e);
color[e]='grey';
}
}
handle(v);
color[v]='black';
}
}
深度优先搜索(DFS):DFS很像树的先序遍历,这里采用递归的方法。
//深度优先搜索(DFS)
Graph.prototype.DFS=function(firstV,handle){
//初始化图的颜色
var color=this.initColor();
//从某个顶点开始依次递归访问
this.DFSVisit(firstV,color,handle);
}
Graph.prototype.DFSVisit=function(v,color,handle){
color[v]='grey';
handle(v);
//获取跟顶点v相关的顶点
var list=this.edges.get(v);
for(var i=0;i<list.length;i++){
var e=list[i];
if(color[e]=='white'){
this.DFSVisit(e,color,handle);
}
}
color[v]='black';
}
最后附上图的基本操作:
//图
function Graph(){
//属性
this.vertexes=[];//顶点
this.edges=new Map();//边
//方法
//添加方法(邻接表)
//添加顶点
Graph.prototype.addVertex=function(v){
this.vertexes.push(v);
this.edges.set(v,[]);
}
//添加边
Graph.prototype.addEdge=function(v1,v2){
this.edges.get(v1).push(v2);
this.edges.get(v2).push(v1);
}
//toString方法
Graph.prototype.toString=function(){
var res='';
for(var i=0;i<this.vertexes.length;i++){
res+=this.vertexes[i]+'->';
var vedge=this.edges.get(this.vertexes[i]);
for(var j=0;j<vedge.length;j++){
res+=vedge[j]+' ';
}
res+='\n';
}
return res;
}
//初始化图的颜色,白色代表未被访问过,灰色代表被访问过但未探索过,黑色代表被访问过且被探索过
Graph.prototype.initColor=function(){
var color=[];
for(var i=0;i<this.vertexes.length;i++){
color[this.vertexes[i]]='white';
}
return color;
}
//广度优先搜索(BFS)
Graph.prototype.BFS=function(firstV,handle){
//1.初始化图的颜色
var color= this.initColor();
//2.创建一个数组
var array=new Array();
//3.将顶点加入到数组中
array.push(firstV);
//4.循环从数组中取出元素并加入相关元素
while(array.length!=0){
var v=array.shift();
var list=this.edges.get(v);
color[v]='grey';
for(var i=0;i<list.length;i++){
var e=list[i];
if(color[e]=='white'){
array.push(e);
color[e]='grey';
}
}
handle(v);
color[v]='black';
}
}
//深度优先搜索(DFS)
Graph.prototype.DFS=function(firstV,handle){
//初始化图的颜色
var color=this.initColor();
//从某个顶点开始依次递归访问
this.DFSVisit(firstV,color,handle);
}
Graph.prototype.DFSVisit=function(v,color,handle){
color[v]='grey';
handle(v);
//获取跟顶点v相关的顶点
var list=this.edges.get(v);
for(var i=0;i<list.length;i++){
var e=list[i];
if(color[e]=='white'){
this.DFSVisit(e,color,handle);
}
}
color[v]='black';
}
}
//使用图
var graph=new Graph();
var vertexes=['A','B','C','D','E','F','G','H','I'];
for(var i=0;i<vertexes.length;i++){
graph.addVertex(vertexes[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');
graph.addEdge('E','I');
console.log(graph.toString());
// A->B C D
// B->A E F
// C->A D G
// D->A C G H
// E->B I
// F->B
// G->C D
// H->D
// I->E
var str='';
graph.BFS('A',function(v){
str+=v+' ';
});
console.log('BFS:'+str);//BFS:A B C D E F G H I
var str1='';
graph.DFS('A',function(v){
str1+=v+' ';
})
console.log('dfs:'+str1);//dfs:A B E I F C D G H
结果: