邻接表代码 单向 + 双向 (存有向边 无向边)

本文详细介绍了图的邻接表存储方式,包括单向和双向图的实现方法,并给出了具体的代码示例。通过使用结构体和数组,有效地实现了图的存储。

记得存无向边的邻接表 好像有个名字来着...忘了

打习惯了上面那东西 现在感觉存单向的邻接表好难打

具体实现步骤见百度 那个马桶上看算法不错(名字怪怪的)

这里只放一下代码=-=因为找不到上面那家伙了 应该是被挤下去了

单向实现:

定义1 结构体 Edge {

int u,v,w;//u点 到 v点 有一条有向边连接 边权为 w

}edge[2333];

定义2 数组 int first[2333],next[2333];

前者 first[node] 意为 与 node 相连的 第一条遍历的 边 (网上大多都说要全赋初值为-1 其实不然)

后者 next[node] 意为 遍历完 第 node 条边后 应遍历哪条边 没有则为0 (同上括号则为-1)

Tip: 从零的话 判断只需 ! 就好 多省力~

代码: ( 读入 + 存储 边 )

for (int a = 1 ; a <= m ; a ++)//m为边数 如果后面用不到m 则循环1可为 while (m--)
{
	scanf("%d%d%d",&edge[a].u,&edge[a].v,&edge[a].w);
	next[a] = first[edge[a].u];
	first[edge[a].u] = a;
}

 

 

双向实现:

定义1 结构体 Edge {

int to,next,w;

}edge[6666];//要开边数两倍 边权w存的话...应该不太标准

定义2 数组 int first[6666];//next在上面保存了 单向要在上面保存也可以 不过不太直观就是

定义3 int tot;//记录边数 然后在edge数组尾部添加边 充分利用空间 真是太美妙了OvO

void add(int x,int y,int w)
{
	edge[++tot].v = w;
	edge[tot].to = y;
	edge[tot].next = first[x];
	first[x] = tot;
}
int main()
{
	scanf("%d%d",&n,&m);
		for (int a = 1 ; a <= m ; a ++)
		{
			scanf("%d%d%d",&x,&y,&z);
			add(x,y,z);
			add(y,x,z);
		}
}

 

这里采用子程序 add 来实现 为什么呢 (居然还问为什么)

 

看主程序 (x,y) 和 (y,x) 很明显 这样子比较省力

当然 你如果要把单向的打两遍也没人说你 题目也过得了

鲁迅 : 体面给谁看呢~

<think>嗯,用户问的是如何用邻接表表示图。邻接表是一种常见的图存储方式,适用于稀疏图,可以节省空间。首先,我得回忆一下邻接表的结构。邻接表通常是一个数组或者字典,每个元素对应图中的一个顶点,然后每个顶点维护一个链表或者列表,存储所有与该顶点直接相连的边或者相邻顶点。那具体怎么实现呢?可能用Python的话,可以用字典或者列表来构建。比如,每个顶点作为键,对应的值是一个列表,里面存的是相邻顶点。比如,顶点0连接到顶点1顶点2,那么邻接表就是{0: [1,2],...}。或者也可以用类来定义顶点,包含相邻顶点的列表。然后要考虑图的类型,是有向图还是无向图。如果是无向图,添加边的时候需要双向处理。比如,添加边(u,v)的话,u的列表里加v,v的列表里加u。而有向图则只需要单向添加。 接下来,可能需要实现添加顶点边的函数。比如,添加顶点时,确保顶点存在在邻接表中;添加边时,检查顶点是否存在,然后更新对应的列表。 代码的大致结构可能像这样:定义一个Graph类,初始化时用字典或者defaultdict来存储邻接表。添加顶点边的方法。然后可能需要遍历或者打印邻接表的方法。用户可能需要代码示例,所以得写出Python的实现。比如使用collections.defaultdict(list)来方便地管理每个顶点的邻接列表。然后给出添加顶点边的方法,以及一个打印邻接表的函数。 还要考虑是否支持权值,如果是带权图的话,邻接表里每个元素可能是一个元组,包含相邻顶点权重。但用户的问题里没有提到权重,所以可能暂时不考虑,或者可以提一下扩展的方法。最后,给出示例代码,并解释每个部分的作用。比如,创建图的实例,添加边,打印邻接表。然后测试代码是否正确。 相关问题的话,可能需要涉及邻接矩阵与邻接表的区别,如何遍历邻接表表示的图(BFS、DFS),如何在邻接表中处理权重,以及如何检测环等。</think>以下是使用Python实现邻接表表示图的完整方案: ```python from collections import defaultdict class Graph: def __init__(self): self.adj_list = defaultdict(list) def add_edge(self, u, v, directed=False): """添加边的方法 :param u: 起始顶点 :param v: 目标顶点 :param directed: 是否为有向图(默认无向) """ self.adj_list[u].append(v) if not directed: # 如果是无向图,添加反向边 self.adj_list[v].append(u) def print_adj_list(self): """打印邻接表""" for vertex in self.adj_list: neighbors = ", ".join(map(str, self.adj_list[vertex])) print(f"{vertex} -> {neighbors}") # 示例用法 if __name__ == "__main__": g = Graph() g.add_edge(0, 1) # 无向边 g.add_edge(0, 4) g.add_edge(1, 2) g.add_edge(1, 3) g.add_edge(4, 3, directed=True) # 有向边 print("邻接表表示:") g.print_adj_list() ``` 代码解释: 1. 使用`defaultdict(list)`创建自动初始化的邻接表容器 2. `add_edge`方法同时支持有向图无向图,通过directed参数控制 3. 无向图添加边时会自动添加反向边,保持对称性 4. print_adj_list方法提供可视化输出,便于调试 输出示例: ``` 邻接表表示: 0 -> 1, 4 1 -> 0, 2, 3 4 -> 0, 3 2 -> 1 3 -> 1, 4 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值