邻接表,存储方法跟树的孩子链表示法相类似,是一种顺序分配和链式分配相结合的存储结构。如这个表头结点所对应的顶点存在相邻顶点,则把相邻顶点依次存放于表头结点所指向的单向链表中。
对于无向图来说,使用邻接表进行存储也会出现数据冗余,表头结点A所指链表中存在一个指向C的表结点的同时,表头结点C所指链表也会存在一个指向A的表结点。
如下为具体的代码实现:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
//无向图
//表结点
function ArcNode(){
this.adjvex = null;//该弧所指向的顶点的位置
this.nextarc = null;//指向下一条弧的指针
this.info = null;//指向相关信息的指针
};
function VNode(){
this.data = null;//顶点信息
this.firstarc = null;//指向第一条依附该点顶点的弧的指针
};
function ALGraph(){
this.vertices = [];
this.vexnum = 0;//图的当前顶点数
this.arcnum = 0;//图的当前弧数
this.kind = null;//图的种类标志
};
//定位函数
function locateVex(g,v1){
var i;
for(i=0;i<g.vexnum;i++){
if(g.vertices[i].data == v1){
return i;
}
if(i >= g.vexnum){
return -1;
}
}
};
//创建无向图
function createUDG(g,arcArr){
var p1,p2;
var i,j,k;
var v1,v2;
for(i = 0;i<g.vexnum;i++){
var vnode = new VNode();
vnode.data = i;
vnode.firstarc = null;
g.vertices[i] = vnode;
}
for(k = 0;k<g.arcnum;k++){
var arc = arcArr[k];
v1 = arc.tail;//弧尾
v2 = arc.head;//弧头
i = locateVex(g,v1);
j = locateVex(g,v2);
//生成一个新表结点
p1 = new ArcNode();
p1.adjvex = j;
p1.nextarc = g.vertices[i].firstarc;
g.vertices[i].firstarc = p1;
p2 = new ArcNode;
p2.adjvex = i;
p2.nextarc = g.vertices[j].firstarc;
g.vertices[j].firstarc = p2;
}
};
function countUDG(g){
var i,j;
for(i=0;i<g.vexnum;i++){
var p = g.vertices[i].firstarc;
var output = "";
while(p != null){
output += "->" + p.adjvex;
p = p.nextarc;
}
console.log(i + "->" + output);
}
}
//测试
(function main(){
var g = new ALGraph();
g.vexnum = 5;//总顶点数
g.arcnum = 6;//总弧数
var arcArr = [{
tail:0,
head:1
},{
tail:0,
head:2
},{
tail:0,
head:4
},{
tail:1,
head:2
},{
tail:2,
head:3
},{
tail:3,
head:4
}];
createUDG(g,arcArr);
countUDG(g);
})();
</script>
</head>
<body>
</body>
</html>