在图论中,深度优先遍历(Depth First Search, DFS)和广度优先遍历(Breadth First Search, BFS)是两种常用的图遍历算法。它们在搜索图中的节点时具有不同的策略和优缺点。本文将详细介绍这两种遍历算法的理论知识,并通过C语言代码示例演示它们的实现方式及应用场景。
一、深度优先遍历(DFS)
深度优先遍历算法是一种先深后广的遍历策略。它从图中的某个顶点开始,沿着一条路径尽可能深地搜索,直到到达最深的顶点,然后再回溯到上一个节点,继续搜索其他路径,直到搜索完整个图。DFS通常采用递归或栈来实现。
理论知识:
-
递归实现: 使用递归函数来实现DFS算法,每次访问一个顶点时,递归地访问它的邻居节点,直到没有未访问的邻居节点为止。
-
栈实现: 使用栈数据结构来实现DFS算法,将当前访问的顶点入栈,然后依次访问其邻居节点,并将未访问的邻居节点入栈,直到栈为空为止。
C语言实现:
下面是用C语言实现DFS算法的示例代码:
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTICES 100
typedef struct Node {
int vertex;
struct Node* next;
} Node;
typedef struct {
int numVertices;
Node* adjList[MAX_VERTICES];
int visited[MAX_VERTICES];
} Graph;
Graph* createGraph(int numVertices) {
Graph* graph = (Graph*)malloc(sizeof(Graph));
graph->numVertices = numVertices;
for (int i = 0; i < numVertices; i++) {
graph->adjList[i] = NULL;
graph->visited[i] = 0;
}
return graph;
}
void addEdge(Graph* graph, int src, int dest) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->vertex = dest;
newNode->next = graph->adjList[src];
graph->adjList[src] = newNode;
}
void DFS(Graph* graph, int vertex) {
graph->visited[vertex] = 1;
printf("%d ", vertex);
Node* temp = graph->adjList[vertex];
while (temp) {
int adjVertex = temp->vertex;
if (!(graph->visited[adjVertex])) {
DFS(graph, adjVertex);
}
temp = temp->next;
}
}
int main() {
Graph* graph = createGraph(5);
addEdge(graph, 0, 1);
addEdge(graph, 0, 2);
addEdge(graph, 1, 2);
addEdge(graph, 1, 3);
addEdge(graph, 2, 3);
addEdge(graph, 3, 4);
printf("深度优先遍历结果:");
DFS(graph, 0);
return 0;
}
二、广度优先遍历(BFS)
广度优先遍历算法是一种先广后深的遍历策略。它从图中的某个顶点开始,依次访问该顶点的所有邻居节点,然后再依次访问邻居节点的邻居节点,直到遍历完整个图。BFS通常采用队列来实现。
理论知识:
- 队列实现: 使用队列数据结构来实现BFS算法,将当前访问的顶点入队列,然后依次访问其邻居节点,并将未访问的邻居节点入队列,直到队列为空为止。
C语言实现:
下面是用C语言实现BFS算法的示例代码:
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTICES 100
typedef struct Node {
int vertex;
struct Node* next;
} Node;
typedef struct {
int numVertices;
Node* adjList[MAX_VERTICES];
int visited[MAX_VERTICES];
} Graph;
Graph* createGraph(int numVertices) {
Graph* graph = (Graph*)malloc(sizeof(Graph));
graph->numVertices = numVertices;
for (int i = 0; i < numVertices; i++) {
graph->adjList[i] = NULL;
graph->visited[i] = 0;
}
return graph;
}
void addEdge(Graph* graph, int src, int dest) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->vertex = dest;
newNode->next = graph->adjList[src];
graph->adjList[src] = newNode;
}
void BFS(Graph* graph, int startVertex) {
int queue[MAX_VERTICES];
int front = 0, rear = 0;
graph->visited[startVertex] = 1;
queue[rear++] = startVertex;
while (front < rear) {
int currentVertex = queue[front++];
printf("%d ", currentVertex);
Node* temp = graph->adjList[currentVertex];
while (temp) {
int adjVertex = temp->vertex;
if (!(graph->visited[adjVertex])) {
graph->visited[adjVertex] = 1;
queue[rear++] = adjVertex;
}
temp = temp->next;
}
}
}
int main() {
Graph* graph = createGraph(5);
addEdge(graph, 0, 1);
addEdge(graph, 0, 2);
addEdge(graph, 1, 2);
addEdge(graph, 1, 3);
addEdge(graph, 2, 3);
addEdge(graph, 3, 4);
printf("广度优先遍历结果:");
BFS(graph, 0);
return 0;
}
通过以上的理论介绍和C语
言代码示例,我们深入了解了深度优先遍历(DFS)和广度优先遍历(BFS)这两种常用的图遍历算法,并学习了它们的实现方式及应用场景。在实际应用中,根据具体情况选择合适的遍历算法,将有助于解决各种图相关的问题。