您的位置:首页 > 其它

数组模拟实现邻接表

2015-03-08 18:59 274 查看
图的边的表示方法,有很多。像邻接矩阵、边集数组、邻接表等。其中,第三者的时空复杂度应该是最优的。但是实现却需要比较麻烦的链表,但是我们也可以用数组来模拟链表,使编程的复杂度进一步降低。

这种算法:遍历所有的边的时间复杂度是O(M),M表示边的总数,空间复杂度也是O(M)。在最坏情况下,查询i与j是否有边的时间复杂度是O(N)。

这篇文章主要写给P(Pascal)党,在Cpp中,链表的实现方式较为简单(有现成的库),所以也没必要用这种办法。说是模拟实现邻接表,其实是模拟实现链表。接下来看类型定义:

type
E=record
too,next,capa:longint;//(too 表示该条边指向的点,next表示该条边指向的下一条边,capa表示该条边的权值)
end;
var
edge:array[1..100000] of E;//edge是边表
nedge:longint;//(表示总的边数)
head:array[1..100000]  of longint;//(head[i]表示第i个点的第一条边在边表的位置)


建树的过程如下(N个点,M条边):

procedure addedge(a,b:longint);
begin
inc(nedge); edge[nedge].next:=head[a];
edge[nedge].too=b;head[a]=nedge;
end;
//Main
readln(n,m);
nedge:=0;
fillchar(head,sizeof(head),0);
for  i:=1 to M do begin
read(a,b);
addedge(a,b);
addedge(b,a);
end;


访问与k相邻的所有点:

t:=head[k];
while ( t>0) do begin
v:=edge[t].too;
t:=edge[t].next;
end;


算法实现原理如下:建树时,找到上面那条边,把这条边“倒挂”在上面,遍历的时候,只要顺着扫过来就好了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: