📅  最后修改于: 2023-12-03 15:42:19.195000             🧑  作者: Mango
这是 GATE-CS-2017(套装2)中的一道题目,主要考察图的遍历和迭代算法。
给定一张无向图 G(V,E),其中 V 表示节点集合,E 表示边集合。你需要实现一个函数 countLeafVertices(G)
,它能够返回图中的叶子节点(degree 为 1 的节点)的数量。
函数原型如下:
def countLeafVertices(G):
# TODO: count leaf vertices in the graph
pass
函数参数说明:
G
: 无向图 G,用一个邻接表表示。邻接表是一个长度为 |V| 的列表,列表的第 i 项表示节点 i 的邻居。函数返回值说明:
题目要求求解图中的叶子节点数量,我们可以通过遍历图的方式来求解。遍历的方式有很多种,这里提供两种常见的遍历方式:
DFS(深度优先搜索)是常用的图遍历算法,它从图的某一个顶点出发开始遍历,直到所有的可达节点都被访问过为止,具体算法过程如下:
下面是 Python 实现的 DFS 算法:
# 深度优先搜索
def dfs(v, visited, adj):
visited[v] = True
count = 1 # 默认情况下,v 是叶子节点
# 遍历 v 的邻居节点
for w in adj[v]:
if not visited[w]:
count += dfs(w, visited, adj)
return count
在 dfs(v, visited, adj)
函数中,v
表示当前节点,visited
表示图中所有节点的访问情况(初始时都为 False),adj
是图的邻接矩阵。函数返回的是以 v
为根节点所构成的子树中叶子节点的数量。
调用 countLeafVertices(G)
函数的时候,我们可以随机挑选一个节点作为根节点开始遍历,最后把所有节点的结果累加起来。所以函数的实现可以写成这样:
def countLeafVertices(G):
n = len(G)
visited = [False] * n
count = 0
# 遍历图中的所有节点
for v in range(n):
if not visited[v]:
degree = len(G[v]) # 当前节点的度数
if degree == 1: # 当前节点是叶子节点
count += 1
else: # 当前节点不是叶子节点
count += dfs(v, visited, G)
return count
BFS(广度优先搜索)是另一种常见的图遍历算法,它从图的某一个顶点出发开始遍历,按照距离从近到远的顺序进行遍历,直到所有的可达节点都被访问过为止,具体算法过程如下:
下面是 Python 实现的 BFS 算法:
# 宽度优先搜索
def bfs(v, visited, adj):
queue = [v] # 起始节点入队
visited[v] = True
count = 1 # 默认情况下,v 是叶子节点
# 遍历队列中的所有节点
while queue:
w = queue.pop(0) # 取出队列头部的节点
for x in adj[w]: # 遍历 w 的所有邻居节点 x
if not visited[x]:
visited[x] = True
count += 1 # x 是w的叶子节点
queue.append(x) # 将 x 入队
return count
与 DFS 类似,BFS 遍历也要遍历图中的所有节点,然后每个节点作为根节点分别计算以它为根节点的子树中叶子节点的数量。最后把所有节点的结果累加起来。函数的实现可以写成这样:
def countLeafVertices(G):
n = len(G)
visited = [False] * n
count = 0
# 遍历图中的所有节点
for v in range(n):
if not visited[v]:
degree = len(G[v]) # 当前节点的度数
if degree == 1: # 当前节点是叶子节点
count += 1
else: # 当前节点不是叶子节点
count += bfs(v, visited, G)
return count
最终实现的代码如下:
# 深度优先搜索
def dfs(v, visited, adj):
visited[v] = True
count = 1 # 默认情况下,v 是叶子节点
# 遍历 v 的邻居节点
for w in adj[v]:
if not visited[w]:
count += dfs(w, visited, adj)
return count
# 宽度优先搜索
def bfs(v, visited, adj):
queue = [v] # 起始节点入队
visited[v] = True
count = 1 # 默认情况下,v 是叶子节点
# 遍历队列中的所有节点
while queue:
w = queue.pop(0) # 取出队列头部的节点
for x in adj[w]: # 遍历 w 的所有邻居节点 x
if not visited[x]:
visited[x] = True
count += 1 # x 是w的叶子节点
queue.append(x) # 将 x 入队
return count
def countLeafVertices(G):
n = len(G)
visited = [False] * n
count = 0
# 遍历图中的所有节点
for v in range(n):
if not visited[v]:
degree = len(G[v]) # 当前节点的度数
if degree == 1: # 当前节点是叶子节点
count += 1
else: # 当前节点不是叶子节点
count += dfs(v, visited, G)
return count
# 门| GATE-CS-2017(套装2)|第 64 题
这是 GATE-CS-2017(套装2)中的一道题目,主要考察图的遍历和迭代算法。
## 题目描述
给定一张无向图 G(V,E),其中 V 表示节点集合,E 表示边集合。你需要实现一个函数 `countLeafVertices(G)`,它能够返回图中的叶子节点(degree 为 1 的节点)的数量。
函数原型如下:
```python
def countLeafVertices(G):
# TODO: count leaf vertices in the graph
pass
函数参数说明:
G
: 无向图 G,用一个邻接表表示。邻接表是一个长度为 |V| 的列表,列表的第 i 项表示节点 i 的邻居。函数返回值说明:
题目要求求解图中的叶子节点数量,我们可以通过遍历图的方式来求解。遍历的方式有很多种,这里提供两种常见的遍历方式:
DFS(深度优先搜索)是常用的图遍历算法,它从图的某一个顶点出发开始遍历,直到所有的可达节点都被访问过为止。
BFS(广度优先搜索)是另一种常见的图遍历算法,它从图的某一个顶点出发开始遍历,按照距离从近到远的顺序进行遍历,直到所有的可达节点都被访问过为止。
# 深度优先搜索
def dfs(v, visited, adj):
visited[v] = True
count = 1 # 默认情况下,v 是叶子节点
# 遍历 v 的邻居节点
for w in adj[v]:
if not visited[w]:
count += dfs(w, visited, adj)
return count
# 宽度优先搜索
def bfs(v, visited, adj):
queue = [v] # 起始节点入队
visited[v] = True
count = 1 # 默认情况下,v 是叶子节点
# 遍历队列中的所有节点
while queue:
w = queue.pop(0) # 取出队列头部的节点
for x in adj[w]: # 遍历 w 的所有邻居节点 x
if not visited[x]:
visited[x] = True
count += 1 # x 是w的叶子节点
queue.append(x) # 将 x 入队
return count
def countLeafVertices(G):
n = len(G)
visited = [False] * n
count = 0
# 遍历图中的所有节点
for v in range(n):
if not visited[v]:
degree = len(G[v]) # 当前节点的度数
if degree == 1: # 当前节点是叶子节点
count += 1
else: # 当前节点不是叶子节点
count += dfs(v, visited, G)
return count
# 门| GATE-CS-2017(套装2)|第 64 题
这是 GATE-CS-2017(套装2)中的一道题目,主要考察图的遍历和迭代算法。
## 题目描述
给定一张无向图 G(V,E),其中 V 表示节点集合,E 表示边集合。你需要实现一个函数 `countLeafVertices(G)`,它能够返回图中的叶子节点(degree 为 1 的节点)的数量。
函数原型如下:
```python
def countLeafVertices(G):
# TODO: count leaf vertices in the graph
pass
函数参数说明:
G
: 无向图 G,用一个邻接表表示。邻接表是一个长度为 |V| 的列表,列表的第 i 项表示节点 i 的邻居。函数返回值说明:
题目要求求解图中的叶子节点数量,我们可以通过遍历图的方式来求解。遍历的方式有很多种,这里提供两种常见的遍历方式:
DFS(深度优先搜索)是常用的图遍历算法,它从图的某一个顶点出发开始遍历,直到所有的可达节点都被访问过为止,具体算法过程如下:
在 DFS 算法中,我们需要每个节点作为根节点分别计算以它为根节点的子树中叶子节点的数量,最后把所有节点的结果累加起来。
BFS(广度优先搜索)是另一种常见的图遍历算法,它从图的某一个顶点出发开始遍历,按照距离从近到远的顺序进行遍历,直到所有的可达节点都被访问过为止,具体算法过程如下:
在 BFS 算法中,我们同样需要每个节点作为根节点分别计算以它为根节点的子树中叶子节点的数量,最后把所有节点的结果累加起来。
函数 countLeafVertices(G)
的具体实现中,我们可以先遍历图中的所有节点,判断当前节点的度数,如果是叶子节点则计数器加一,并跳过本轮遍历。如果不是叶子节点,则调用 DFS 或 BFS 算法计算以该节点为根节点的子树中叶子节点的数量,最后累加到计数器中,继续下一轮的遍历。
最终实现的代码如下:
# 深度优先搜索
def dfs(v, visited, adj):
visited[v] = True
count = 1 # 默认情况下,v 是叶子节点
# 遍历 v 的邻居节点
for w in adj[v]:
if not visited[w]:
count += dfs(w, visited, adj)
return count
# 宽度优先搜索
def bfs(v, visited, adj):
queue = [v] # 起始节点入队
visited[v] = True
count = 1 # 默认情况下,v 是叶子节点
# 遍历队列中的所有节点
while queue:
w = queue.pop(0) # 取出队列头部的节点
for x in adj[w]: # 遍历 w 的所有邻居节点 x
if not visited[x]:
visited[x] = True
count += 1 # x 是w的叶子节点
queue.append(x) # 将 x 入队
return count
def countLeafVertices(G):
n = len(G)
visited = [False] * n
count = 0
# 遍历图中的所有节点
for v in range(n):
if not visited[v]:
degree = len(G[v]) # 当前节点的度数
if degree == 1: # 当前节点是叶子节点
count += 1
else: # 当前节点不是叶子节点
count += dfs(v, visited, G) # 或者调用 bfs 函数
return count
该函数的时间复杂度是 O(|V| + |E|),空间复杂度也是 O(|V| + |E|)。