链式前向星与邻接表对比

本文图片及数据

对于这样一张有向图:
这里写图片描述

输入边的顺序如下:
1 2
2 3
3 4
1 3
4 1
1 5
4 5

对于邻接表来说是这样的:
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; head[3] = 2;
edge[3].to = 3; edge[3].next = 0; head[1] = 3;
edge[4].to = 1; edge[4].next = -1; head[4] = 4;
edge[5].to = 5; edge[5].next = 3; head[1] = 5;
edge[6].to = 5; edge[6].next = 4; head[4] = 6;

(以起点为1举例):
head[1] = 5 (以1为起点的第一条边的位置) -> edge[5].to = 5 (终点) -> edge[5].next = 3(同一起点下一条边的位置) ->edge[3].to = 3(第二条边的终点) -> edge[3].next = 0 -> edge[0].to = 2(第三条边的终点) ->edge[0].next = -1 (没下一条边)

简化来说就是:
1 -> 5 -> 3 -> 2
可以看到链式前向星和邻接表除了顺序不一样,其他的可以说是一样的。

看一下链式前向星的代码:

const int maxn = 10005;   //点的最大个数

int head[maxn], cnt=0;//head用来表示以i为起点的第一条边存储的位置,cnt读入边的计数器

struct Edge
{
    int next; //同一起点的上一条边的储存位置
    int to; //第i条边的终点
    int w; //第i条边权重
};
Edge edge[maxn];

void add(int u,int v,int w)  //读入边
{
    edge[cnt].w = w;
    edge[cnt].to = v;
    edge[cnt].next = head[u];
    head[u] = cnt++;
}

void read()  //遍历所有边
{
    for(int i=0; i<=n; i++)
        for(int j=head[i]; j!=-1; j=edge[j].next)
}

我觉得链式前向星和邻接表的思想是一样的,区别就是:邻接表是用链表实现的,可以动态的增加边,
而链式前向星是用结构体数组实现的,是静态的,需要一开始知道数据范围,开好数组大小。
相比之下,邻接表灵活,链式前向星好写。

如有理解不对的地方,希望可以告诉我。

### 关于邻接表链式前向星的数据结构例题实现 #### 使用邻接表表示图并解决最短路径问题 对于给定的一个无权有向图,使用邻接表来表示该图,并求解从源点到其他各顶点的最短距离。 ```cpp #include <iostream> #include <vector> #include <queue> using namespace std; const int MAXN = 1e5 + 7; int dist[MAXN]; bool vis[MAXN]; // 定义边结构体 struct Edge { int to, next; } edge[MAXN * 2]; // 假设最多有MAXN*2条边 int head[MAXN], cnt; // head数组记录每个节点的第一条出边编号;cnt用于计数当前已有的边数量 void addEdge(int from, int to) { // 添加一条from->to方向上的边 edge[++cnt].to = to; edge[cnt].next = head[from]; head[from] = cnt; } void bfs(int startNode) { queue<int> q; memset(dist, -1, sizeof(dist)); dist[startNode] = 0; q.push(startNode); while (!q.empty()) { int cur = q.front(); q.pop(); for (int i = head[cur]; ~i; i = edge[i].next) { int v = edge[i].to; if (dist[v] == -1) { dist[v] = dist[cur] + 1; q.push(v); } } } } ``` 这段代码展示了如何利用邻接表构建一张简单的无权有向图以及通过广度优先搜索算法计算起始节点到达其余各个节点之间的最小步数[^1]。 #### 利用链式前向星处理加权图中的最短路问题 下面的例子说明了怎样运用链式前向星存储带权重的边信息,并借助Dijkstra算法找出单源最短路径: ```cpp #include <cstring> #include <algorithm> #define INF 0x3f3f3f3f using namespace std; typedef pair<int,int> PII; const int N=1e5+10,M=N<<1; int n,m,S,T,d[N]; PII e[M]; int h[N],ne[M],w[M],idx; bool st[N]; inline void add(int a,int b,int c){ e[idx]=make_pair(b,c),ne[idx]=h[a],h[a]=idx++; } void dijkstra(){ memset(d,INF,sizeof d); priority_queue<PII,vector<PII>,greater<>> heap; d[S]=0; heap.push({d[S],S}); while(heap.size()){ auto t=heap.top(); heap.pop(); int ver=t.second,dis=t.first; if(st[ver]) continue; st[ver]=true; for(int i=h[ver];~i;i=ne[i]){ int j=e[i].first; if(d[j]>dis+w[i]){ d[j]=dis+w[i]; heap.push({d[j],j}); } } } } ``` 此部分实现了基于链式前向星的方式保存每条边上附带的成本值,并且采用了堆优化版迪杰斯特拉(Dijkstra)算法去查找由指定起点出发至其它任意终点间的最优路线长度[^2]。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值