- 数据结构与算法
- DSA - 首页
- DSA - 概述
- DSA - 环境搭建
- DSA - 算法基础
- DSA - 渐进分析
- 数据结构
- DSA - 数据结构基础
- DSA - 数据结构和类型
- DSA - 数组数据结构
- 链表
- DSA - 链表数据结构
- DSA - 双向链表数据结构
- DSA - 循环链表数据结构
- 栈与队列
- DSA - 栈数据结构
- DSA - 表达式解析
- DSA - 队列数据结构
- 搜索算法
- DSA - 搜索算法
- DSA - 线性搜索算法
- DSA - 二分搜索算法
- DSA - 插值搜索
- DSA - 跳跃搜索算法
- DSA - 指数搜索
- DSA - 斐波那契搜索
- DSA - 子列表搜索
- DSA - 哈希表
- 排序算法
- DSA - 排序算法
- DSA - 冒泡排序算法
- DSA - 插入排序算法
- DSA - 选择排序算法
- DSA - 归并排序算法
- DSA - 希尔排序算法
- DSA - 堆排序
- DSA - 桶排序算法
- DSA - 计数排序算法
- DSA - 基数排序算法
- DSA - 快速排序算法
- 图数据结构
- DSA - 图数据结构
- DSA - 深度优先遍历
- DSA - 广度优先遍历
- DSA - 生成树
- 树数据结构
- DSA - 树数据结构
- DSA - 树的遍历
- DSA - 二叉搜索树
- DSA - AVL树
- DSA - 红黑树
- DSA - B树
- DSA - B+树
- DSA - 伸展树
- DSA - 字典树
- DSA - 堆数据结构
- 递归
- DSA - 递归算法
- DSA - 使用递归实现汉诺塔
- DSA - 使用递归实现斐波那契数列
- 分治法
- DSA - 分治法
- DSA - 最大最小问题
- DSA - Strassen矩阵乘法
- DSA - Karatsuba算法
- 贪心算法
- DSA - 贪心算法
- DSA - 旅行商问题(贪心法)
- DSA - Prim最小生成树
- DSA - Kruskal最小生成树
- DSA - Dijkstra最短路径算法
- DSA - 地图着色算法
- DSA - 分数背包问题
- DSA - 带截止日期的作业排序
- DSA - 最优合并模式算法
- 动态规划
- DSA - 动态规划
- DSA - 矩阵链乘法
- DSA - Floyd-Warshall算法
- DSA - 0-1背包问题
- DSA - 最长公共子序列算法
- DSA - 旅行商问题(动态规划法)
- 近似算法
- DSA - 近似算法
- DSA - 顶点覆盖算法
- DSA - 集合覆盖问题
- DSA - 旅行商问题(近似算法)
- 随机化算法
- DSA - 随机化算法
- DSA - 随机化快速排序算法
- DSA - Karger最小割算法
- DSA - Fisher-Yates洗牌算法
- DSA有用资源
- DSA - 问答
- DSA - 快速指南
- DSA - 有用资源
- DSA - 讨论
深度优先搜索 (DFS) 算法
深度优先搜索 (DFS) 算法
深度优先搜索 (DFS) 算法是一种用于搜索图或树数据结构所有顶点的递归算法。此算法以深度优先的方式遍历图,并使用栈来记住在任何迭代中遇到死胡同时要开始搜索的下一个顶点。
如上例所示,DFS 算法首先从 S 遍历到 A、D、G、E、B,然后到 F,最后到 C。它采用以下规则。
规则 1 - 访问相邻的未访问顶点。将其标记为已访问。显示它。将其压入栈中。
规则 2 - 如果未找到相邻顶点,则从栈中弹出顶点。(它将弹出栈中所有没有相邻顶点的顶点。)
规则 3 - 重复规则 1 和规则 2,直到栈为空。
| 步骤 | 遍历 | 描述 |
|---|---|---|
| 1 | ![]() |
初始化栈。 |
| 2 | ![]() |
将 S 标记为已访问,并将其压入栈中。探索 S 的任何未访问的相邻节点。我们有三个节点,我们可以选择其中任何一个。在本例中,我们将按字母顺序选择节点。 |
| 3 | ![]() |
将 A 标记为已访问,并将其压入栈中。探索 A 的任何未访问的相邻节点。S 和 D 都与 A 相邻,但我们只关心未访问的节点。 |
| 4 | ![]() |
访问 D,将其标记为已访问,并将其压入栈中。这里,我们有 B 和 C 节点,它们与 D 相邻,并且都未访问。但是,我们仍将按字母顺序选择。 |
| 5 | ![]() |
我们选择 B,将其标记为已访问,并将其压入栈中。这里 B 没有未访问的相邻节点。因此,我们从栈中弹出 B。 |
| 6 | ![]() |
我们检查栈顶以返回到上一个节点,并检查它是否有任何未访问的节点。在这里,我们发现 D 在栈顶。 |
| 7 | ![]() |
现在,D 唯一未访问的相邻节点是 C。因此,我们访问 C,将其标记为已访问,并将其压入栈中。 |
由于 C 没有未访问的相邻节点,因此我们继续弹出栈,直到找到一个具有未访问相邻节点的节点。在本例中,没有这样的节点,我们继续弹出直到栈为空。
示例
以下是深度优先搜索 (DFS) 算法在各种编程语言中的实现 -
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX 5
struct Vertex {
char label;
bool visited;
};
//stack variables
int stack[MAX];
int top = -1;
//graph variables
//array of vertices
struct Vertex* lstVertices[MAX];
//adjacency matrix
int adjMatrix[MAX][MAX];
//vertex count
int vertexCount = 0;
//stack functions
void push(int item) {
stack[++top] = item;
}
int pop() {
return stack[top--];
}
int peek() {
return stack[top];
}
bool isStackEmpty() {
return top == -1;
}
//graph functions
//add vertex to the vertex list
void addVertex(char label) {
struct Vertex* vertex = (struct Vertex*) malloc(sizeof(struct Vertex));
vertex->label = label;
vertex->visited = false;
lstVertices[vertexCount++] = vertex;
}
//add edge to edge array
void addEdge(int start,int end) {
adjMatrix[start][end] = 1;
adjMatrix[end][start] = 1;
}
//display the vertex
void displayVertex(int vertexIndex) {
printf("%c ",lstVertices[vertexIndex]->label);
}
//get the adjacent unvisited vertex
int getAdjUnvisitedVertex(int vertexIndex) {
int i;
for(i = 0; i < vertexCount; i++) {
if(adjMatrix[vertexIndex][i] == 1 && lstVertices[i]->visited == false) {
return i;
}
}
return -1;
}
void depthFirstSearch() {
int i;
//mark first node as visited
lstVertices[0]->visited = true;
//display the vertex
displayVertex(0);
//push vertex index in stack
push(0);
while(!isStackEmpty()) {
//get the unvisited vertex of vertex which is at top of the stack
int unvisitedVertex = getAdjUnvisitedVertex(peek());
//no adjacent vertex found
if(unvisitedVertex == -1) {
pop();
} else {
lstVertices[unvisitedVertex]->visited = true;
displayVertex(unvisitedVertex);
push(unvisitedVertex);
}
}
//stack is empty, search is complete, reset the visited flag
for(i = 0;i < vertexCount;i++) {
lstVertices[i]->visited = false;
}
}
int main() {
int i, j;
for(i = 0; i < MAX; i++) { // set adjacency
for(j = 0; j < MAX; j++) // matrix to 0
adjMatrix[i][j] = 0;
}
addVertex('S'); // 0
addVertex('A'); // 1
addVertex('B'); // 2
addVertex('C'); // 3
addVertex('D'); // 4
addEdge(0, 1); // S - A
addEdge(0, 2); // S - B
addEdge(0, 3); // S - C
addEdge(1, 4); // A - D
addEdge(2, 4); // B - D
addEdge(3, 4); // C - D
printf("Depth First Search: ");
depthFirstSearch();
return 0;
}
输出
Depth First Search: S A D B C
//C++ code for Depth First Traversal
#include <iostream>
#include <array>
#include <vector>
constexpr int MAX = 5;
struct Vertex {
char label;
bool visited;
};
//stack variables
std::array<int, MAX> stack;
int top = -1;
//graph variables
//array of vertices
std::array<Vertex*, MAX> lstVertices;
//adjacency matrix
std::array<std::array<int, MAX>, MAX> adjMatrix;
//vertex count
int vertexCount = 0;
//stack functions
void push(int item) {
stack[++top] = item;
}
int pop() {
return stack[top--];
}
int peek() {
return stack[top];
}
bool isStackEmpty() {
return top == -1;
}
//graph functions
//add vertex to the vertex list
void addVertex(char label) {
Vertex* vertex = new Vertex;
vertex->label = label;
vertex->visited = false;
lstVertices[vertexCount++] = vertex;
}
//add edge to edge array
void addEdge(int start, int end) {
adjMatrix[start][end] = 1;
adjMatrix[end][start] = 1;
}
//display the vertex
void displayVertex(int vertexIndex) {
std::cout << lstVertices[vertexIndex]->label << " ";
}
//get the adjacent unvisited vertex
int getAdjUnvisitedVertex(int vertexIndex) {
for (int i = 0; i < vertexCount; i++) {
if (adjMatrix[vertexIndex][i] == 1 && !lstVertices[i]->visited) {
return i;
}
}
return -1;
}
//mark first node as visited
void depthFirstSearch() {
lstVertices[0]->visited = true;
//display the vertex
displayVertex(0);
//push vertex index in stack
push(0);
while (!isStackEmpty()) {
//get the unvisited vertex of vertex which is at top of the stack
int unvisitedVertex = getAdjUnvisitedVertex(peek());
//no adjacent vertex found
if (unvisitedVertex == -1) {
pop();
} else {
lstVertices[unvisitedVertex]->visited = true;
displayVertex(unvisitedVertex);
push(unvisitedVertex);
}
}
//stack is empty, search is complete, reset the visited flag
for (int i = 0; i < vertexCount; i++) {
lstVertices[i]->visited = false;
}
}
int main() {
for (int i = 0; i < MAX; i++) { //set adjacency
for (int j = 0; j < MAX; j++) { // matrix to 0
adjMatrix[i][j] = 0;
}
}
addVertex('S');
addVertex('A');
addVertex('B');
addVertex('C');
addVertex('D');
addEdge(0, 1);
addEdge(0, 2);
addEdge(0, 3);
addEdge(1, 4);
addEdge(2, 4);
addEdge(3, 4);
std::cout << "Depth First Search: ";
depthFirstSearch();
return 0;
}
输出
Depth First Search: S A D B C
//Java program for Depth First Traversal
public class DepthFirstSearch {
private static final int MAX = 5;
private static class Vertex {
char label;
boolean visited;
}
private static int[] stack = new int[MAX];
private static int top = -1;
private static Vertex[] lstVertices = new Vertex[MAX];
private static int[][] adjMatrix = new int[MAX][MAX];
private static int vertexCount = 0;
private static void push(int item) {
stack[++top] = item;
}
private static int pop() {
return stack[top--];
}
private static int peek() {
return stack[top];
}
private static boolean isStackEmpty() {
return top == -1;
}
private static void addVertex(char label) {
Vertex vertex = new Vertex();
vertex.label = label;
vertex.visited = false;
lstVertices[vertexCount++] = vertex;
}
private static void addEdge(int start, int end) {
adjMatrix[start][end] = 1;
adjMatrix[end][start] = 1;
}
private static void displayVertex(int vertexIndex) {
System.out.print(lstVertices[vertexIndex].label + " ");
}
private static int getAdjUnvisitedVertex(int vertexIndex) {
for (int i = 0; i < vertexCount; i++) {
if (adjMatrix[vertexIndex][i] == 1 && !lstVertices[i].visited) {
return i;
}
}
return -1;
}
private static void depthFirstSearch() {
lstVertices[0].visited = true;
displayVertex(0);
push(0);
while (!isStackEmpty()) {
int unvisitedVertex = getAdjUnvisitedVertex(peek());
if (unvisitedVertex == -1) {
pop();
} else {
lstVertices[unvisitedVertex].visited = true;
displayVertex(unvisitedVertex);
push(unvisitedVertex);
}
}
for (int i = 0; i < vertexCount; i++) {
lstVertices[i].visited = false;
}
}
public static void main(String[] args) {
for (int i = 0; i < MAX; i++) {
for (int j = 0; j < MAX; j++) {
adjMatrix[i][j] = 0;
}
}
addVertex('S'); // 0
addVertex('A'); // 1
addVertex('B'); // 2
addVertex('C'); // 3
addVertex('D'); // 4
addEdge(0, 1); // S - A
addEdge(0, 2); // S - B
addEdge(0, 3); // S - C
addEdge(1, 4); // A - D
addEdge(2, 4); // B - D
addEdge(3, 4); // C - D
System.out.print("Depth First Search: ");
depthFirstSearch();
}
}
输出
Depth First Search: S A D B C
#Python program for Depth First Traversal
MAX = 5
class Vertex:
def __init__(self, label):
self.label = label
self.visited = False
#stack variables
stack = []
top = -1
#graph variables
#array of vertices
lstVertices = [None] * MAX
#adjacency matrix
adjMatrix = [[0] * MAX for _ in range(MAX)]
#vertex count
vertexCount = 0
#stack functions
def push(item):
global top
top += 1
stack.append(item)
def pop():
global top
item = stack[top]
del stack[top]
top -= 1
return item
def peek():
return stack[top]
def isStackEmpty():
return top == -1
#graph functions
#add vertex to the vertex list
def addVertex(label):
global vertexCount
vertex = Vertex(label)
lstVertices[vertexCount] = vertex
vertexCount += 1
#add edge to edge array
def addEdge(start, end):
adjMatrix[start][end] = 1
adjMatrix[end][start] = 1
#Display the Vertex
def displayVertex(vertexIndex):
print(lstVertices[vertexIndex].label, end=' ')
def getAdjUnvisitedVertex(vertexIndex):
for i in range(vertexCount):
if adjMatrix[vertexIndex][i] == 1 and not lstVertices[i].visited:
return i
return -1
def depthFirstSearch():
lstVertices[0].visited = True
displayVertex(0)
push(0)
while not isStackEmpty():
unvisitedVertex = getAdjUnvisitedVertex(peek())
if unvisitedVertex == -1:
pop()
else:
lstVertices[unvisitedVertex].visited = True
displayVertex(unvisitedVertex)
push(unvisitedVertex)
for i in range(vertexCount):
lstVertices[i].visited = False
for i in range(MAX):
for j in range(MAX):
adjMatrix[i][j] = 0
addVertex('S') # 0
addVertex('A') # 1
addVertex('B') # 2
addVertex('C') # 3
addVertex('D') # 4
addEdge(0, 1) # S - A
addEdge(0, 2) # S - B
addEdge(0, 3) # S - C
addEdge(1, 4) # A - D
addEdge(2, 4) # B - D
addEdge(3, 4) # C - D
print("Depth First Search:", end=' ')
depthFirstSearch()
输出
Depth First Search: S A D B C
点击查看 深度优先搜索 (BFS) 算法 的 C 语言实现
DFS 算法的复杂度
时间复杂度
DFS 算法的时间复杂度表示为 O(V + E) 的形式,其中 V 是节点数,E 是边数。
空间复杂度
DFS 算法的空间复杂度为 O(V)。
广告






