Python图的定义与种类
中等3图是什么?用点和线画出你的朋友圈
想象一下,你的班级里有30个同学,每个人都是一个“点”。如果你和同桌是好朋友,就在你们两个点之间连一条“线”;如果你还认识隔壁班的同学,那就再连一条线。这样,所有的点和线就组成了一张关系网,在编程里我们把它叫做图。
图是计算机科学里非常重要的一种数据结构,它专门用来表示事物之间的联系。你可以用它来模拟现实世界的各种关系,比如:地铁线路图(站点是点,轨道是线)、社交网络(用户是点,关注关系是线)、迷宫(房间是点,通道是线)等等。
图的组成:顶点和边
一张图由两样东西组成:
- 顶点(Vertex):也叫节点,就是上面说的“点”。在你班级的例子中,每个同学就是一个顶点。
- 边(Edge):就是连接两个顶点的“线”。如果两个同学认识,就在他们之间画一条边。
在代码中,我们通常用数字或字符串来给顶点起名字,比如 1、2、3 或 "小明"、"小红"。
图的两种主要种类
现实中的关系有“单向”和“双向”之分,所以图也分成两种。
1. 无向图:没有方向的朋友关系
在无向图里,边是没有方向的。如果你连了我,我同时也连了你。就像你和你的同桌:你们互相认识,所以画一条直线就够了,不用画箭头。
生活中的例子:
- 家庭关系中的“亲兄弟姐妹”——哥哥和弟弟彼此是兄弟,关系是双向的。
- 教室里两个人一起玩——A和B是朋友,B和A也是朋友。
Python 代码表示:
我们可以用字典(dict)来存储每个顶点的“邻居”列表。比如顶点 1 的邻居是 [2],顶点 2 的邻居是 [1, 3],这表示 1-2 之间有边,2-3 之间也有边。
# 无向图:每个顶点存储它的邻居(双向关系)
undirected_graph = {
1: [2], # 顶点1的邻居:2
2: [1, 3], # 顶点2的邻居:1和3
3: [2] # 顶点3的邻居:2
}
print("无向图:", undirected_graph)
注意:如果 1 连了 2,那么 2 的列表里必须也有 1,否则就不是无向图了。
2. 有向图:有方向的关注关系
在有向图里,边是有箭头的,表示方向。比如你关注了某位up主,但up主不一定关注你,所以这条关系是单向的。
生活中的例子:
- 微博粉丝关系:小明关注了小红,但小红没有关注小明。
- 单行道:道路只能朝一个方向开。
- 作业抄袭:小刚抄了小强的作业,但小强没抄小刚的。
Python 代码表示:
有向图只需要记录“谁指向谁”,也就是每个顶点存储它指向的顶点,而不需要反过来也存储。比如 1 -> 2 表示从1出发箭头指向2,但2的列表里不一定要有1。
# 有向图:每个顶点存储它指向的顶点(出边)
directed_graph = {
1: [2], # 1 指向 2(1→2)
2: [3], # 2 指向 3(2→3)
3: [] # 3 没有指向任何人(出边为空)
}
print("有向图:", directed_graph)
新手容易犯的错误
❌ 错误1:无向图漏了反向边
比如你写了:
graph_wrong = {
1: [2],
2: [3], # 注意:这里缺了 1
3: [2]
}
这样 1 认为它认识 2,但 2 的邻居里却没有 1,导致图中 1-2 这条边变成单向的,不再是正确的无向图。
正确做法: 每添加一条无向边,必须在两个顶点的邻居列表里都写上对方。
❌ 错误2:有向图误写成双向
比如你要表示“小明关注小红”,却把小红也写上“关注小明”:
follow_wrong = {
"小明": ["小红"],
"小红": ["小明"] # 小红本来没关注小明,这里多写了
}
这就会变成双向关注,不符合原来的意思。
正确做法: 有向图只记录实际有的方向,不要自己脑补反向。
❌ 错误3:顶点编号不连续或误解
有时学生会误以为顶点必须从0或1开始连续编号。其实可以用任何字符串:
# 完全可以用名字当顶点
graph_friends = {
"小明": ["小红", "小刚"],
"小红": ["小明"],
"小刚": ["小明"]
}
这样更贴近生活。
完整可运行的示例
下面是一个完整的程序,它同时创建了无向图和有向图,并打印出它们的结构。你可以直接复制到Python环境中运行。
# 完整示例:无向图和有向图的创建与输出
# 1. 无向图:用班级朋友关系
# 顶点:1号同学,2号同学,3号同学
# 边:1-2 是朋友,2-3 是朋友
undirected_graph = {
1: [2], # 1认识2
2: [1, 3], # 2认识1和3
3: [2] # 3认识2
}
print("无向图(朋友关系):")
print(undirected_graph)
# 2. 有向图:用微博关注关系
# 顶点:小明、小红、小刚
# 边:小明→小红(关注),小红→小刚(关注)
follow_graph = {
"小明": ["小红"], # 小明关注了小红
"小红": ["小刚"], # 小红关注了小刚
"小刚": [] # 小刚没有关注任何人
}
print("\n有向图(微博关注关系):")
print(follow_graph)
# 3. 简单测试:看看2号同学的朋友有哪些
print("\n2号同学的朋友有:", undirected_graph[2])
# 输出:2号同学的朋友有: [1, 3]
# 4. 看看小明关注了谁
print("小明关注了:", follow_graph["小明"])
# 输出:小明关注了: ['小红']
运行结果:
无向图(朋友关系):
{1: [2], 2: [1, 3], 3: [2]}
有向图(微博关注关系):
{'小明': ['小红'], '小红': ['小刚'], '小刚': []}
2号同学的朋友有: [1, 3]
小明关注了: ['小红']
相关知识点指引
学完了图的定义和两种基本种类,你下一步可以探索:
- 图的更多表示方法:除了用字典,还可以用邻接矩阵(像表格一样记录每对顶点之间有没有边),或者用边列表(直接存所有边的起点和终点)。
- 图的遍历:怎么从一个顶点出发,走遍所有顶点?这就是深度优先搜索(DFS) 和 广度优先搜索(BFS)。
- 加权图:给边加上一个数字,代表“距离”、“时间”或“代价”。比如地图上两个城市之间的高速公路里程。
- 实际应用:用图做最短路径(导航)、社交网络推荐、迷宫寻路等。
图论是编程竞赛和信息学必修的内容,好好掌握哦!
例题精讲
在无向图中,一条边连接两个顶点,那么这条边表示的两个顶点之间的关系是?
在有向图中,边是具有方向的,通常用箭头表示,例如边(a,b)表示从顶点a指向顶点b,但不能从b到a。
在一个包含5个顶点的无向图中,若每个顶点的度数都是2,则该图共有多少条边?
在Python中,可以使用字典来表示图的邻接表,其中键表示顶点,值表示与该顶点相邻的顶点列表。
以下Python代码使用邻接表创建一个简单的无向图,包含顶点0,1,2,边(0,1)和(0,2)。请补全代码。
graph = {0: [1, 2],
1: [___],
2: [0]}
print(graph)