深度优先搜索
算法描述:
搜索时,只要尽可能,就在图中尽量深入。
深度优先搜索总是对最近才发现的结点v的出发边进行探索,直到该结点的所有出发边都被发现为止。一旦
结点v的所有出发边都被发现,探索则回溯到v的前驱结点,来探索该前驱结点的出发边。该过程一直持续到从
源节点可以到达的所有结点都被发现为止。
深度优先搜索树:
同广度优先搜索树一样,树中除根结点外的每个结点的父节点,为图中访问到该结点的前驱结点。
算法实现:
1.邻接矩阵法
int visited[N];
int edges[N][N];
void DFS(int start)
{
visited[start] = 1;
for(int i = 0; i < N; ++i)
{
if (edges[start][i] == 1 && visited[i] == 0)
{
DFS(i);
}
}
}
2. 邻接链表法
int visited[N];
vector<int> v[N];
void DFS(int start)
{
visited[start] = 1;
for(int i = 0; i < v[start].size(); ++i)
{
if (visited[i] == 0)
{
DFS(i);
}
}
}
3. 一个python的实现
这里不使用递归,使用的是栈数据结构,类似于 $Bfs$,栈结构能保证:当前出栈的点是前一个出栈的点的邻接点。
graph = {
"A": ["B", "C"],
"B": ["A", "C", "D"],
"C": ["A", "B", "D", "E"],
"D": ["B", "C", "E", "F"],
"E": ["C", "D"],
"F": ["D"]
}
def DFS(graph, s):
stack = []
seen = {}
stack.append(s)
seen.add(s)
while (len(stack) > 0):
vertex = stack.pop()
nodes = graph[vertex]
for w in nodes:
if w not in seen:
stack.add(w)
seen.add(w)
print(vertex)
邻接链表法时间复杂度分析:
使用聚合分析法进行分析,易知每个结点都会调用一次 $DFS(i)$,所以 $DFS(i)$ 和 $visited[start] = 1$ 这两行代码的代价为 $O(V)$。
循环和判断操作的次数为所有的邻接边,故代价为 $O(E)$,所以总的时间复杂度为 $O(V+E)$。
浙公网安备 33010602011771号