算法基础---图论

一、图的存储

三种数据结构:

 邻接矩阵

1. 定义:邻接矩阵是一个二维数组,其中`matrix[i][j]`表示顶点i到顶点j是否有边。对于无向图,这个矩阵是对称的。

2. 优点:
   - 简单直观。
   - 方便检查任意两个顶点间是否存在边。
   - 适合表示稠密图,因为其空间复杂度与图的大小无关。

3. 缺点:
   - 空间复杂度高,为O(V^2),其中V是顶点数。
   - 不适合表示稀疏图,因为大量的空间被浪费在表示不存在的边上。
   - 遍历邻接点的效率低(需要遍历整行或整列)。

 邻接表

1. 定义:邻接表是一个数组,其中每个元素是一个链表,链表中的每个节点代表一个顶点的邻接顶点。

2. 优点:
   - 空间复杂度相对较低,为O(V + E),其中E是边数。
   - 适合表示稀疏图。
   - 便于遍历任一顶点的所有邻接点。

3. 缺点:
   - 检查两个顶点间是否存在边相对较慢。
   - 相比邻接矩阵,实现稍微复杂。

 链式前向星

1. 定义:链式前向星是邻接表的一种优化实现,通过两个数组来实现。一个存储边的信息(如终点和权重),另一个存储每个顶点的边表头部。

2. 优点:
   - 高效地存储和遍历图的边。
   - 空间效率和邻接表相似,适用于稀疏图。
   - 适合于边数远大于点数的图。

3. 缺点:
   - 实现复杂度高于邻接表。
   - 检查两个顶点间是否存在边的效率较低。

 总结

- 邻接矩阵适用于表示稠密图,简单但空间效率低。
- 邻接表适用于表示稀疏图,空间效率较高,但查找边的效率较低。
- 链式前向星是邻接表的优化版,适用于边数远大于点数的图,实现较为复杂。

链式前向星代码:
   创建

struct Edge
{
    int to, w, next; // to - 目标节点, w - 权重, next - 下一个边
}
    Edge[M * 2]; // 边的数组,大小是边的数量的两倍

    int head[N]; // 头节点数组

    int tot, n, m; // tot - 总边数当前索引, n - 节点数, m - 边数

    void addedge(int u, int v, int w) // u - 起点, v - 终点, w - 权重
    {
        edge[++tot].to = v;
        edge[tot].w = w;
        edge[tot].next = head[u];
        head[u] = tot; // 新增边的头节点是u
    }
}

   遍历

for(int i=head[x];i;i =edge[i].next){
	...
}

特点: 存各种图都很适合,但不能快速查询一条边是否存在,也不能方便地对一个点的出边进行排序。

优点是边是带编号的,有时会非常有用,而且如果 cnt 的初始值为奇数,存双向边时 i ^ 1 即是 i 的反边

在一些对空间严格的题目上也可以使用,比邻接表vector写法的空间更好

    

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Faelan.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值