C语言实现邻接表的深度优先遍历和广度优先遍历
时间: 2023-08-31 09:22:19 浏览: 57
### 回答1:
邻接表是用于存储图的数据结构,深度优先遍历和广度优先遍历是两种常见的图遍历算法。
下面是C语言实现邻接表的深度优先遍历和广度优先遍历的代码:
首先,定义邻接表的结构体:
```c
typedef struct EdgeNode {
int adjvex; // 邻接点下标
struct EdgeNode *next; // 指向下一个邻接点的指针
} EdgeNode;
typedef struct VertexNode {
int data; // 顶点数据
EdgeNode *firstedge; // 指向第一个邻接点的指针
} VertexNode, AdjList[MAXV];
typedef struct {
AdjList adjList; // 邻接表
int vexnum, edgenum; // 顶点数和边数
} GraphAdjList;
```
然后,实现深度优先遍历:
```c
// 访问顶点 v
void visit(int v) {
printf("%d ", v);
}
// 从顶点 v 开始深度优先遍历
void DFS(GraphAdjList G, int v, int visited[]) {
visited[v] = 1; // 标记顶点 v 已被访问
visit(v); // 访问顶点 v
EdgeNode *p = G.adjList[v].firstedge;
while (p != NULL) {
int w = p->adjvex; // 获取邻接点下标
if (!visited[w]) { // 若邻接点未被访问,则递归访问它
DFS(G, w, visited);
}
p = p->next;
}
}
// 遍历整个图,对每个未被访问的顶点调用 DFS
void DFSTraverse(GraphAdjList G) {
int visited[MAXV] = {0}; // 初始化 visited 数组为 0
for (int i = 0; i < G.vexnum; i++) {
if (!visited[i]) {
DFS(G, i, visited);
}
}
}
```
最后,实现广度优先遍历:
```c
// 从顶点 v 开始广度优先遍历
void BFS(GraphAdjList G, int v, int visited[]) {
int queue[MAXV], front = 0, rear = 0;
visit(v); // 访问顶点 v
visited[v] = 1; // 标记顶点 v 已被访问
queue[rear++] = v; // v 入队
while (front != rear) { // 队列非空
int w = queue[front++]; // 出队
EdgeNode *p = G.adjList[w].firstedge;
while (p != NULL) {
int u = p->adjvex; // 获取邻接点下标
if (!visited[u]) { // 若邻接点未被访问,则访问它并将其入队
visit(u);
visited[u] = 1;
queue[rear++] = u;
}
p = p->next;
}
}
}
// 遍历整个图,对每个未被访问的顶点调用 BFS
void BFSTraverse(GraphAdjList G) {
int visited[MAXV] = {0}; // 初始化 visited 数组为 0
for (int i = 0; i < G.vexnum; i++) {
if (!visited[i]) {
BFS(G, i, visited);
}
}
}
```
其中,MAXV 表示最大顶点数。
### 回答2:
邻接表是一种图的存储结构,C语言可以通过链表来实现邻接表的深度优先遍历和广度优先遍历。
深度优先遍历:
深度优先遍历是一种以深度为优先的遍历方法,它从起始顶点开始,访问其所有未访问过的邻接顶点,然后再访问这些邻接顶点的邻接顶点。在C语言中,我们可以使用递归函数来实现深度优先遍历邻接表。具体步骤如下:
1. 创建一个数组visited,用于记录每个顶点是否被访问过。
2. 选择一个起始顶点v,将visited[v]标记为已访问。
3. 遍历顶点v的邻接链表,对于每个未访问过的邻接顶点u,调用递归函数DFS(u),继续深度优先遍历。
4. 重复步骤3,直到图中所有的顶点都被访问过。
具体的C语言代码如下:
```
#include <stdlib.h>
#include <stdio.h>
struct Node {
int data;
struct Node* next;
};
void DFS(int v, struct Node** adj_list, int* visited) {
struct Node* temp = adj_list[v];
visited[v] = 1;
printf("%d ", v);
while (temp != NULL) {
int u = temp->data;
if (!visited[u]) {
DFS(u, adj_list, visited);
}
temp = temp->next;
}
}
void addEdge(struct Node** adj_list, int src, int dest) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = dest;
newNode->next = adj_list[src];
adj_list[src] = newNode;
newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = src;
newNode->next = adj_list[dest];
adj_list[dest] = newNode;
}
int main() {
int num_vertices = 5;
struct Node** adj_list = (struct Node**)malloc(num_vertices * sizeof(struct Node*));
int* visited = (int*)calloc(num_vertices, sizeof(int));
for (int i = 0; i < num_vertices; i++) {
adj_list[i] = NULL;
}
addEdge(adj_list, 0, 1);
addEdge(adj_list, 0, 2);
addEdge(adj_list, 1, 2);
addEdge(adj_list, 2, 0);
addEdge(adj_list, 2, 3);
addEdge(adj_list, 3, 3);
printf("深度优先遍历结果:\n");
DFS(2, adj_list, visited);
return 0;
}
```
广度优先遍历:
广度优先遍历是一种以广度为优先的遍历方法,它从起始顶点开始,访问其所有邻接顶点,然后再访问这些邻接顶点的邻接顶点,依次类推,直到图中所有的顶点都被访问过。在C语言中,可以使用队列来实现广度优先遍历邻接表。具体步骤如下:
1. 创建一个数组visited,用于记录每个顶点是否被访问过。
2. 创建一个空队列queue,将起始顶点v入队,并将visited[v]标记为已访问。
3. 从队列中取出一个顶点u,访问u,将其所有邻接顶点入队并标记为已访问。
4. 重复步骤3,直到队列为空。
具体的C语言代码如下:
```
#include <stdlib.h>
#include <stdio.h>
struct Node {
int data;
struct Node* next;
};
void BFS(int v, struct Node** adj_list, int* visited) {
struct Node* queue = (struct Node*)malloc(sizeof(struct Node));
struct Node* front = queue;
struct Node* rear = queue;
visited[v] = 1;
printf("%d ", v);
while (front != NULL) {
v = front->data;
front = front->next;
struct Node* temp = adj_list[v];
while (temp != NULL) {
int u = temp->data;
if (!visited[u]) {
visited[u] = 1;
printf("%d ", u);
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
new_node->data = u;
new_node->next = NULL;
rear->next = new_node;
rear = new_node;
}
temp = temp->next;
}
}
}
void addEdge(struct Node** adj_list, int src, int dest) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = dest;
newNode->next = adj_list[src];
adj_list[src] = newNode;
newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = src;
newNode->next = adj_list[dest];
adj_list[dest] = newNode;
}
int main() {
int num_vertices = 5;
struct Node** adj_list = (struct Node**)malloc(num_vertices * sizeof(struct Node*));
int* visited = (int*)calloc(num_vertices, sizeof(int));
for (int i = 0; i < num_vertices; i++) {
adj_list[i] = NULL;
}
addEdge(adj_list, 0, 1);
addEdge(adj_list, 0, 2);
addEdge(adj_list, 1, 2);
addEdge(adj_list, 2, 0);
addEdge(adj_list, 2, 3);
addEdge(adj_list, 3, 3);
printf("广度优先遍历结果:\n");
BFS(2, adj_list, visited);
return 0;
}
```
这样,我们就可以使用C语言来实现邻接表的深度优先遍历和广度优先遍历了。
### 回答3:
C语言实现邻接表的深度优先遍历和广度优先遍历的步骤如下:
深度优先遍历(DFS):
1. 声明一个栈,并将起始顶点压入栈中。
2. 创建一个布尔数组,用来标记每个顶点是否被访问过,并将起始顶点标记为已访问。
3. 循环执行以下步骤,直到栈为空:
1) 弹出栈顶元素,并输出该顶点。
2) 查找该顶点的邻接顶点:
a) 若邻接顶点未被访问过,则将其压入栈中,并标记为已访问。
b) 若邻接顶点已被访问过,则继续查找下一个邻接顶点。
4. 遍历结束。
广度优先遍历(BFS):
1. 声明一个队列,并将起始顶点入队。
2. 创建一个布尔数组,用来标记每个顶点是否被访问过,并将起始顶点标记为已访问。
3. 循环执行以下步骤,直到队列为空:
1) 出队一个顶点,并输出该顶点。
2) 查找该顶点的邻接顶点:
a) 若邻接顶点未被访问过,则将其入队,并标记为已访问。
b) 若邻接顶点已被访问过,则继续查找下一个邻接顶点。
4. 遍历结束。
在这两种遍历中,我们使用一个布尔数组来记录顶点的访问情况,避免重复访问。同时,栈和队列分别用来记录当前正在访问的顶点,以便按照深度优先或广度优先的顺序进行遍历。
以上是C语言实现邻接表的深度优先遍历和广度优先遍历的基本步骤,可以通过循环和递归等不同方式来实现具体代码。