首页 > 代码库 > 图的存储方式

图的存储方式

昨天 听caicai讲了几种关于图的存储方式 又学了好多  家有caicai 如有一宝 -> 转自 晓爷

下面 我所讲的 都是基于 有向图的建图方式 

i:

map[a][b] ---最基础的邻接矩阵  直接用二维数组

ii:

 1 struct graph
 2 {
 3     int num;  // ---指向 下一个顶点 ( 表示当前已经与 该顶点相邻的个数 )
 4     int next[x]; // -- 与 该顶点 第( x+1 )个相邻的点的标号
 5     int dist[x]; // -- 与 该顶点 第 ( x+1 )个相邻的点与该点之间的距离 --通过它来进行松弛操作
 6     
 7 }mp[y] 
 8 bool vis[y] // -- 各个顶点 是否已经被访问过 在某个状态中 如 在spfa中 表示 是否已经入队
 9 int dist[y] // -- 源点 -> 各个顶点的距离
10 // -- 这里的 next 和 dist 数组 是相对应的 所以 数组大小声明为相同
11 int main()
12 {
13     int temp;
14     scanf( "%d %d %d" , &from , &to , &dist );
15     temp = mp[from].num;
16     mp[from].next[temp] = to;
17     mp[from].dist[temp] = dist;
18     mp[from].num++;
19     // temp++ 这是 错的 千万不要犯这种错误
20 }
21 
22 // 或者 可以用下面 这种方式 代码更加简洁 但可读性没有上面的好
23     mp[from].next[ mp[from].num ] = to;
24     mp[from].dist[ mp[from].num++ ] = dist;
View Code

iii:

 1 // y -- 顶点个数
 2 // x -- 与 该顶点 相邻的顶点个数
 3 
 4 struct graph
 5 {
 6     int num;  // ---指向 下一个顶点 ( 表示当前已经与 该顶点相邻的个数 )
 7     int next[x]; // -- 与 该顶点 第( x+1 )个相邻的点的标号
 8     int dist[x]; // -- 与 该顶点 第 ( x+1 )个相邻的点与该点之间的距离 --通过它来进行松弛操作
 9     
10 }mp[y] 
11 bool vis[y] // -- 各个顶点 是否已经被访问过 在某个状态中 如 在spfa中 表示 是否已经入队
12 int dist[y] // -- 源点 -> 各个顶点的距离
13 // -- 这里的 next 和 dist 数组 是相对应的 所以 数组大小声明为相同
14 
15 iii:
16 
17 // num --- 边的总数 每有一条边的加入 就+1
18 // x --- 顶点的个数
19 struct garph
20 {
21     int to;    // 当结构体标号为num时 相邻的边的顶点
22     int dist;  // 当结构体标号为num时 相邻的边的距离
23     int next;  // 当结构体标号为num时 记录这条边的出发点的前面出现过的结构体标号,就是一个向前查询 类似于一个索引 很高效 通过是否为-1 来判断循环终止 
24 }edge[x*3];    // 边的条数
25 
26 int head[x];   //  指向有着相同源点的顶点的标号   head的下标 即当前边的顶点的下标 
27 
28 void addedge( int from , int to , int dist )
29 {
30     edge[num].to = to;              //传递 相邻边的顶点
31     edge[num].dist = dist;          //传递 距离
32     edge[num].next = head[from];  //通过head数组 来查询在前面的输入中 是否已经出现过相同的源点 如果有 就在此处指向它 方便后面的for遍历查询
33     head[from] = num;             //使顶点标号为from的结点 指向 该结构体标号
34     num++;                        
35 }
36 
37 int main()
38 {
39     memset( head , -1 , sizeof(head) );  // 因为我是从0~n 给顶点标号 那么 -1 是代表无前驱指向 当然  如果是从 1~n的 我当然可以初始化为0
40     scanf( "%d %d %d" , &from , &to , &dist )
41     addedge( from , to , dist );    
42     for( int i = head[now] ; i!=-1 ; i = edge[i].next )//实现方式
43 }
View Code

iV:

上述的存储方式 都是放在二维数组 或者 结构体中 不具备灵活性 我们可以将它放在 容器 vector中 当然 这样可以节省内存 同时我们也要也牺牲时间的代价来获得  用何种方式 还得看具体 情况
通过vector<class>vec[num]  来操作
class---> 基本数据类型 或 自定义数据类型

 

这里 还有一篇 讲的比我更为透彻 超神 -> click it

如果 有任何不对的地方 请给我指出来  为了不误导后面的无意看到此文的人