完成图的深度优先遍历算法、广度优先遍历算法。其中,邻接表的创建相当于创建多个单链表。 每一句代码都需要详细注释
时间: 2024-03-09 14:48:04 浏览: 68
数据结构 图的深度优先遍历和广度优先遍历
5星 · 资源好评率100%
好的,下面是深度优先遍历算法和广度优先遍历算法的代码实现和注释:
## 深度优先遍历算法
### 递归实现
```python
class Graph:
def __init__(self, vertices):
self.vertices = vertices
self.adj_list = [[] for _ in range(vertices)]
def add_edge(self, src, dest):
self.adj_list[src].append(dest)
self.adj_list[dest].append(src)
def dfs_util(self, v, visited):
visited[v] = True
print(v, end=' ')
for i in self.adj_list[v]:
if not visited[i]:
self.dfs_util(i, visited)
def dfs(self, start):
visited = [False] * self.vertices
self.dfs_util(start, visited)
```
深度优先遍历算法使用递归进行实现。首先,我们定义了一个Graph类,包含顶点数和邻接表。我们使用一个列表adj_list来存储邻接表,其中列表的每个元素都是一个空列表,用于存储与该顶点相邻的所有顶点。
接下来,我们定义了一个add_edge方法,用于向图中添加边。此方法接受两个参数:源顶点和目标顶点。我们通过将目标顶点添加到源顶点的邻接表中,以及将源顶点添加到目标顶点的邻接表中,来表示源顶点和目标顶点之间的一条边。
接着,我们定义了一个dfs_util方法,用于实现递归遍历。此方法接受两个参数:当前顶点v和一个布尔值列表visited,表示当前顶点是否被访问过。我们首先将visited[v]设置为True,表示当前顶点已被访问,并将其打印出来。然后,我们遍历与当前顶点相邻的所有顶点,如果某个相邻顶点未被访问,则递归调用dfs_util方法,以此类推。
最后,我们定义了一个dfs方法,用于启动递归遍历。此方法接受一个参数:起始顶点start。我们首先创建一个布尔值列表visited,并将其初始化为False。然后,调用dfs_util方法,以当前顶点和visited列表作为参数开始递归遍历。
### 非递归实现
```python
class Graph:
def __init__(self, vertices):
self.vertices = vertices
self.adj_list = [[] for _ in range(vertices)]
def add_edge(self, src, dest):
self.adj_list[src].append(dest)
self.adj_list[dest].append(src)
def dfs(self, start):
visited = [False] * self.vertices
stack = []
stack.append(start)
while stack:
v = stack.pop()
if not visited[v]:
visited[v] = True
print(v, end=' ')
for i in self.adj_list[v]:
if not visited[i]:
stack.append(i)
```
深度优先遍历算法还可以使用非递归方式实现,我们使用栈来代替递归的系统栈。首先,我们定义了一个Graph类,包含顶点数和邻接表。我们使用一个列表adj_list来存储邻接表,其中列表的每个元素都是一个空列表,用于存储与该顶点相邻的所有顶点。
接下来,我们定义了一个add_edge方法,用于向图中添加边。此方法接受两个参数:源顶点和目标顶点。我们通过将目标顶点添加到源顶点的邻接表中,以及将源顶点添加到目标顶点的邻接表中,来表示源顶点和目标顶点之间的一条边。
接着,我们定义了一个dfs方法,用于实现非递归遍历。此方法接受一个参数:起始顶点start。我们首先创建一个布尔值列表visited,并将其初始化为False。然后,我们创建一个栈stack,并将起始顶点start压入栈中。接下来,我们开始循环,直到栈为空。在每次循环中,我们从栈中弹出一个顶点v。如果当前顶点未被访问过,则将visited[v]设置为True,表示当前顶点已被访问,并将其打印出来。然后,我们遍历与当前顶点相邻的所有顶点,如果某个相邻顶点未被访问,则将其压入栈中,以此类推。
## 广度优先遍历算法
```python
from collections import deque
class Graph:
def __init__(self, vertices):
self.vertices = vertices
self.adj_list = [[] for _ in range(vertices)]
def add_edge(self, src, dest):
self.adj_list[src].append(dest)
self.adj_list[dest].append(src)
def bfs(self, start):
visited = [False] * self.vertices
queue = deque()
queue.append(start)
visited[start] = True
while queue:
v = queue.popleft()
print(v, end=' ')
for i in self.adj_list[v]:
if not visited[i]:
visited[i] = True
queue.append(i)
```
广度优先遍历算法使用队列进行实现。首先,我们导入了Python的collections模块,用于创建双向队列deque。然后,我们定义了一个Graph类,包含顶点数和邻接表。我们使用一个列表adj_list来存储邻接表,其中列表的每个元素都是一个空列表,用于存储与该顶点相邻的所有顶点。
接下来,我们定义了一个add_edge方法,用于向图中添加边。此方法接受两个参数:源顶点和目标顶点。我们通过将目标顶点添加到源顶点的邻接表中,以及将源顶点添加到目标顶点的邻接表中,来表示源顶点和目标顶点之间的一条边。
接着,我们定义了一个bfs方法,用于实现广度优先遍历。此方法接受一个参数:起始顶点start。我们首先创建一个布尔值列表visited,并将其初始化为False。然后,我们创建一个双向队列queue,并将起始顶点start添加到队列中。接下来,我们将visited[start]设置为True,表示起始顶点已被访问。接着,我们开始循环,直到队列为空。在每次循环中,我们从队列的左侧弹出一个顶点v,并将其打印出来。然后,我们遍历与当前顶点相邻的所有顶点,如果某个相邻顶点未被访问,则将其添加到队列的右侧,并将visited[i]设置为True,表示该顶点已被访问,以此类推。
阅读全文