CC++ & Algorithm

Python图的定义与种类

中等3
语言版本:C++Python
概述:图就像一张关系网,用点和线来表示事物之间的联系,有有向图和无向图两种。

图是什么?用点和线画出你的朋友圈

想象一下,你的班级里有30个同学,每个人都是一个“点”。如果你和同桌是好朋友,就在你们两个点之间连一条“线”;如果你还认识隔壁班的同学,那就再连一条线。这样,所有的点和线就组成了一张关系网,在编程里我们把它叫做

图是计算机科学里非常重要的一种数据结构,它专门用来表示事物之间联系。你可以用它来模拟现实世界的各种关系,比如:地铁线路图(站点是点,轨道是线)、社交网络(用户是点,关注关系是线)、迷宫(房间是点,通道是线)等等。


图的组成:顶点和边

一张图由两样东西组成:

  • 顶点(Vertex):也叫节点,就是上面说的“点”。在你班级的例子中,每个同学就是一个顶点。
  • 边(Edge):就是连接两个顶点的“线”。如果两个同学认识,就在他们之间画一条边。

在代码中,我们通常用数字或字符串来给顶点起名字,比如 123"小明""小红"


图的两种主要种类

现实中的关系有“单向”和“双向”之分,所以图也分成两种。

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)
  • 加权图:给边加上一个数字,代表“距离”、“时间”或“代价”。比如地图上两个城市之间的高速公路里程。
  • 实际应用:用图做最短路径(导航)、社交网络推荐迷宫寻路等。

图论是编程竞赛和信息学必修的内容,好好掌握哦!

例题精讲

1单选题

在无向图中,一条边连接两个顶点,那么这条边表示的两个顶点之间的关系是?

A单向关系
B双向关系
C没有关系
D任意关系
2判断题

在有向图中,边是具有方向的,通常用箭头表示,例如边(a,b)表示从顶点a指向顶点b,但不能从b到a。

3单选题

在一个包含5个顶点的无向图中,若每个顶点的度数都是2,则该图共有多少条边?

A5
B10
C2.5
D20
4判断题

在Python中,可以使用字典来表示图的邻接表,其中键表示顶点,值表示与该顶点相邻的顶点列表。

5填空题
以下Python代码使用邻接表创建一个简单的无向图,包含顶点0,1,2,边(0,1)和(0,2)。请补全代码。

graph = {0: [1, 2], 
        1: [___], 
        2: [0]}
print(graph)