因为最近在学tarjan算法,很多博客写的都是用邻接表来存储图。邻接表存储图呢,可以降低时间复杂度为O(m),查询复杂度为O(m)。所以邻接表是对稀疏图非常好的存储方式。
那么接下来呢,我们就开始了解邻接表的两种形式,以前的话,没有仔细的学过哎,好渣,都大二了,才去了解这个==
http://ahalei.blog.51cto.com/4767671/1391988
上面的链接呢,是第一种存储方式,数组模拟,这篇博客写的真的是非常非常好,十分推荐;
http://blog.csdn.net/dgq8211/article/details/7557223
这里呢,有个实例,就是变成模板,这个真的非常爽,模板这个东西就是一点一点积累的哈
#include <stdio.h>
#include <string.h>
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define Max_n 100005
#define Max_e 10005
struct Vertex
{
int head; //head记录某点的的信息,即从E中的哪个下标开始
}V[Max_n];
struct Edge
{
int v,w; //v表示连接点的编号,w表示此边的权值
int next; //next负责连接和此点相关的边
}E[Max_e];
int top; //top记录已用E的个数,且保证每个E独立
void Init()
{
top = 0;
CLR(V,-1);
}
void Add_edge(int u,int v,int w) //演示如何添加边
{
E[top].v = v;
E[top].w = w;
E[top].next = V[u].head; //链表的头插法
V[u].head = top++; //链表的头指针改为此边编号
}
void dfs(int x) //演示如何遍历
{
for(int i = V[x].head; i != -1;i = E[i].next)//i为边在E中的编号
{
int v = E[i].v;
int w = E[i].w;
}
}
第二种呢就是用vector<int>g[N]这种存储方式。
g[]数组存储的是头结点,而vector<int>,存储儿子节点的,因为vector是可边大小,所以呢,存储任意节点都可以。
对于这两种方法呢,我推荐第一种,因为是模拟数组,它的时间复杂度没那么大,有的图用vector过不去。。