图的存储结构:邻接矩阵(邻接表)&链式前向星

【概念】疏松图&稠密图:

疏松图指,点连接的边不多的图,反之(点连接的边多)则为稠密图。

Tips:邻接矩阵与邻接表相比,疏松图多用邻接表,稠密图多用邻接矩阵。


邻接矩阵:

开一个二维数组graph[ ][ ]来记录图中点a与点b之间是否连通,初始化为0(或者-1之类的看情况);如果图中有可忽略的重边(如 只需重边中的最小边或最大边),则保存需要的那条边的边权,但如果有无法忽略的重边,就一定不要用邻接矩阵。

int graph[MAXN][MAXN];

void graphInit()
{
    memset(graph,0,sizeof(graph));
}

void graph_addEdge(int from,int to)
{
    graph[from][to]=1;  

    //如果是有边权的图,把权值赋给graph[from][to]
    //如果是无向无重边图,可以写成graph[from][to]=graph[to][from]=X(对称矩阵);
}


邻接表:

依旧给每个节点编号,邻接表就是在结构体里声明一个to,由点a指向所连接的点b,就是vertex[a].to.push_back(b);记得要初始化。

而且,因为邻接表是用vector存边(push_back),所以不必担心重边丢失的情况;不过,使用邻接表存储图的话,对于两点之间是否连通的查询,相比邻接矩阵,邻接表处于劣势(因为在邻接表里必须遍历整个当前点的to才能判断是否与另一点连通)。

//用vector实现
struct node
{
    vector<int> to;

    //如果要挂边权,就在结构体里增加 int val;即可

}vertex[MAXN];

void graph_init(int n)
{
    for(int i=1;i<=n;i++)
        vertex[i].to.clear();
}

void graph_addEdge(int from,int to)
{
    vertex[from].to.push_back(to);

    //如果是无向边,则写成以下两步:
    //vertex[from].to.push_back(to);
    //vertex[to].to.push_back(from);
}


链式前向星:

本质上是图上所有边以某种特殊方式组成的链表。

通过加边方法,可以知道,如何查询一个点连出的边的方法:

要查询一个点的连出边,我们要先查head,知道这个点最近添加的那条边在哪里(查询结果在这里是j),然后比这条边早一些添加的就是next[j],再早一点的就是next[next[j]],更早一点的是next[next[next[j]]],再早一点的是……,就这样我们一直往时间添加时间更早的边查,直到查到空节点(用来标记链表结束)。



以下是链式前向星的模板,含加边操作、遍历操作的方法:

struct Graph
{
    int head[MAXN];  //每一个节点在容器(数组)中所对应的第一条边的位置
    int next[MAXN];  //每一条边在容器中所对应的同一起点的下一条边的位置
    int to[MAXN];  //真正存储某一条边指向哪一点
    //若要知道每条边的起点,还需开一个数组from[MAXN];

    inline void addEdge(int _from,int _to)
    {
        //加边的方法

        static int q=1;
        //q是静态变量,每次加边,都首先用q指示当前存储边的容器末端(暗示已经为end)

        to[q]=_to;  //在to的末端写入新加边的信息
        next[q]=head[_from];
        //head[_from]表示起点_from最近添加的一条边的位置,然后让新加边的next指向该边的位置
        head[_from]=q++;
        //修改head,使得最近添加的边更新为新边,同时末端向后移动(q++;)以供下一次添加使用
    }
} graph;

void iteration()
{
    //遍历的方法

    int now;  //now 是当前所处的节点编号
    for (int j=idx.head[now]; j; j=idx.next[j])
    {}
    //operate node j,j是now所连接的节点编号
}
时间: 2024-10-11 22:06:29

图的存储结构:邻接矩阵(邻接表)&链式前向星的相关文章

邻接表+链式前向星

(我一个蒟蒻.分不清这两个姐妹qwq 邻接表: 1 -> 2 -> 3 -> 5 2 -> 3 3 -> 4 4 -> 1 -> 5 5 ->^ 链式前向星: edge[0].to = 2;     edge[0].next = -1;     head[1] = 0; edge[1].to = 3;     edge[1].next = -1;     head[2] = 1; edge[2].to = 4;     edge[2],next = -1; 

图的存储结构之邻接表

邻接矩阵的缺点:边数相对顶点较少的图,极大地浪费了存储空间. 把数组与链表相结合的存储方法称为邻接表.(Adjacency List) 邻接表的处理办法: 顶点用一个一维数组存储(较容易读取顶点信息),每个数据元素还需要存储指向第一个邻接点的指针,以便于查找该顶点的边信息. 每个顶点的所有邻接点构成一个线性表(用单链表存储).无向图称为顶点Vi的边表,有向图称为顶点Vi作为弧尾的出边表. 图1  无向图的邻接表结构 data是数据域,存储顶点的信息,firstedge是指针域,指向边表的第一个结

图的存储结构之邻接表(详解)

之前我们介绍过图的邻接矩阵存储法,它的空间和时间复杂度都是N2,现在我来介绍另外一种存储图的方法:邻接表,这样空间和时间复杂度就都是M.对于稀疏图来说,M要远远小于N2.先上数据,如下. 1 2 3 4 5 6 4 5 1 4 9 4 3 8 1 2 5 2 4 6 1 3 7 第一行两个整数n m.n表示顶点个数(顶点编号为1~n),m表示边的条数.接下来m行表示,每行有3个数x y z,表示顶点x到顶点y的边的权值为z.下图就是一种使用链表来实现邻接表的方法. 上面这种实现方法为图中的每一个

单元最短路径算法模板汇总(Dijkstra, BF,SPFA),附链式前向星模板

一:dijkstra算法时间复杂度,用优先级队列优化的话,O((M+N)logN)求单源最短路径,要求所有边的权值非负.若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的. 设road[i][j]表示相邻的i到j的路长U集合存储已经求得的到源点最短路径的节点,S集合表示还没求得的节点dis[i]表示i到源节点(设为0)的最短路径vis[i]=1表示i节点在U集合中 刚开始dis[0]=0,vis[0]=1;dis[i]=maxn,vis[i]=0;for 1 to

图基本算法 图的表示方法 邻接矩阵 邻接表

要表示一个图G=(V,E),有两种标准的表示方法,即邻接表和邻接矩阵.这两种表示法既可用于有向图,也可用于无向图.通常采用邻接表表示法,因为用这种方法表示稀疏图(图中边数远小于点个数)比较紧凑.但当遇到稠密图(|E|接近于|V|^2)或必须很快判别两个给定顶点手否存在连接边时,通常采用邻接矩阵表示法,例如求最短路径算法中,就采用邻接矩阵表示. 图G=<V,E>的邻接表表示是由一个包含|V|个列表的数组Adj所组成,其中每个列表对应于V中的一个顶点.对于每一个u∈V,邻接表Adj[u]包含所有满

图的存储:链式前向星(边集数组)

申明:本文中提及的所有存图结构都用静态数组实现,而非链表. 0.什么是链式前向星 链式前向星是一种存图的结构,例如前向星.邻接矩阵.边表.邻接表等也是存图的结构. 1.链式前向星有何优点 链式前向星:空间利用率高,在各类竞赛中常被使用. 邻接矩阵:需要开N*N的空间,在各类竞赛中常被卡. 邻接表:空间复杂度略小于邻接矩阵,但会被极端数据卡爆,且无法记录权值. 边表:无法迅速判断两点连通性,以至不适用于大多数图的算法. 前向星:具有排序操作,时间复杂度高. 2.同类结构介绍 邻接矩阵:开二维数组,

NYOJ 20 吝啬的国度 【BFS+链式前向星建图,Vector建图】

吝啬的国度 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来.现在,Tom在第S号城市,他有张该国地图,他想知道如果自己要去参观第T号城市,必须经过的前一个城市是几号城市(假设你不走重复的路). 输入 第一行输入一个整数M表示测试数据共有M(1<=M<=5)组 每组测试数据的第一行输入一个正整数N(1<=N<=100000)和一个正整数S(1<=S<=100000

UESTC30-最短路-Floyd最短路、spfa+链式前向星建图

最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的T-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据. 每组数据第一行是两个整数NN ,MM (N≤100N≤100 ,M≤10000M≤1000

最短路 spfa 算法 &amp;&amp; 链式前向星存图

推荐博客  https://i.cnblogs.com/EditPosts.aspx?opt=1 http://blog.csdn.net/mcdonnell_douglas/article/details/54379641 spfa  自行百度 说的很详细 spfa 有很多实现的方法  dfs  队列  栈  都可以 时间复杂度也不稳定 不过一般情况下要比bellman快得多 #include <stdio.h> #include <math.h> #include <st