Fork me on GitHub
数组模拟实现邻接表

数组模拟实现邻接表

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

      这种算法:遍历所有的边的时间复杂度是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;

      算法实现原理如下:建树时,找到上面那条边,把这条边“倒挂”在上面,遍历的时候,只要顺着扫过来就好了。

 

——捐赠我(莱特币):Le8Z8dCsEnzyAztUft3EXEDasZw62VSmT3

 

 

 

分类: OI

posted on 2015-03-09 23:40  HackerVirus  阅读(1533)  评论(0编辑  收藏  举报