怎么用c语言实现有向图和无向图的两种遍历
时间: 2024-01-04 08:00:37 浏览: 36
有向图和无向图是图论中常见的两种图,它们在C语言中可以通过邻接矩阵或邻接表来实现。下面分别介绍两种遍历方式的具体实现:
1. 有向图的遍历:
邻接矩阵实现有向图的遍历,可以使用深度优先搜索(DFS)或广度优先搜索(BFS)算法。在C语言中,可以通过递归函数或者使用栈来实现DFS,通过队列来实现BFS。
邻接表实现有向图的遍历,同样可以使用DFS或BFS算法。通过循环和堆栈来实现DFS,通过循环和队列来实现BFS。
2. 无向图的遍历:
无向图的遍历与有向图类似,同样可以使用DFS和BFS算法来实现。
在C语言中,可以用递归函数或者使用栈来实现DFS,使用队列来实现BFS。对于邻接矩阵和邻接表的实现方式也与有向图的遍历相似。
需要注意的是,在实现过程中,需要标记已经访问过的节点,以避免重复访问和死循环的问题。
总之,通过合理的数据结构和算法设计,可以在C语言中实现有向图和无向图的两种遍历方式。通过深入学习图论和相关算法知识,可以更好地理解和实现这些遍历算法。
相关问题
用c语言实现一个图的两种遍历算法
以下是C语言实现图的深度优先遍历和广度优先遍历的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAXVEX 100 // 最大顶点数
typedef char VertexType; // 顶点类型
typedef int EdgeType; // 边权类型
typedef struct {
VertexType vexs[MAXVEX]; // 顶点集合
EdgeType arc[MAXVEX][MAXVEX]; // 邻接矩阵,可看作边表
int numVertexes, numEdges; // 图中当前的顶点数和边数
} MGraph;
// 初始化图
void initGraph(MGraph *G) {
int i, j, k, weight, n;
printf("请输入顶点数和边数:\n");
scanf("%d%d", &G->numVertexes, &G->numEdges);
// 读入顶点信息
printf("请输入顶点信息:\n");
for (i = 0; i < G->numVertexes; i++) {
scanf("%c", &G->vexs[i]); // 吸收换行符
scanf("%c", &G->vexs[i]);
}
// 初始化邻接矩阵
for (i = 0; i < G->numVertexes; i++) {
for (j = 0; j < G->numVertexes; j++) {
G->arc[i][j] = 0;
}
}
// 读入边信息,建立邻接矩阵
printf("请输入边信息:\n");
for (k = 0; k < G->numEdges; k++) {
printf("请输入边(vi, vj)的下标i, j和权重:\n");
scanf("%d%d%d", &i, &j, &weight);
G->arc[i][j] = weight;
G->arc[j][i] = weight; // 无向图的边是双向的
}
}
// 访问顶点
void visitVertex(VertexType vertex) {
printf("%c ", vertex);
}
// 深度优先遍历
void DFS(MGraph G, int i, bool *visited) {
int j;
visited[i] = true; // 标记当前顶点已访问
visitVertex(G.vexs[i]); // 访问当前顶点
// 从当前顶点出发,递归访问所有未被访问的邻接顶点
for (j = 0; j < G.numVertexes; j++) {
if (G.arc[i][j] != 0 && !visited[j]) {
DFS(G, j, visited);
}
}
}
// 深度优先遍历图
void DFSTraverse(MGraph G) {
int i;
bool visited[MAXVEX];
// 初始化所有顶点都未被访问
for (i = 0; i < G.numVertexes; i++) {
visited[i] = false;
}
// 对每个未被访问过的顶点调用DFS,遍历整个图
for (i = 0; i < G.numVertexes; i++) {
if (!visited[i]) {
DFS(G, i, visited);
}
}
}
// 队列结构体
typedef struct {
int data[MAXVEX];
int front, rear;
} Queue;
// 初始化队列
void initQueue(Queue *Q) {
Q->front = Q->rear = 0;
}
// 入队
void enQueue(Queue *Q, int value) {
Q->data[Q->rear++] = value;
}
// 出队
int deQueue(Queue *Q) {
return Q->data[Q->front++];
}
// 判断队列是否为空
bool isQueueEmpty(Queue Q) {
return Q.front == Q.rear;
}
// 广度优先遍历
void BFS(MGraph G, int i, bool *visited) {
int j, k;
Queue Q;
initQueue(&Q); // 初始化队列
visited[i] = true; // 标记当前顶点已访问
visitVertex(G.vexs[i]); // 访问当前顶点
enQueue(&Q, i); // 将当前顶点入队
while (!isQueueEmpty(Q)) {
j = deQueue(&Q); // 出队顶点
// 遍历所有未被访问的邻接顶点,入队并标记已访问
for (k = 0; k < G.numVertexes; k++) {
if (G.arc[j][k] != 0 && !visited[k]) {
visited[k] = true;
visitVertex(G.vexs[k]);
enQueue(&Q, k);
}
}
}
}
// 广度优先遍历图
void BFSTraverse(MGraph G) {
int i;
bool visited[MAXVEX];
// 初始化所有顶点都未被访问
for (i = 0; i < G.numVertexes; i++) {
visited[i] = false;
}
// 对每个未被访问过的顶点调用BFS,遍历整个图
for (i = 0; i < G.numVertexes; i++) {
if (!visited[i]) {
BFS(G, i, visited);
}
}
}
int main() {
MGraph G;
initGraph(&G); // 初始化图
printf("深度优先遍历结果:\n");
DFSTraverse(G); // 深度优先遍历图
printf("\n广度优先遍历结果:\n");
BFSTraverse(G); // 广度优先遍历图
return 0;
}
```
注意,在代码中的 `MGraph` 结构体中,`vexs` 数组存储的是顶点集合,`arc` 二维数组即邻接矩阵,表示顶点之间是否有边相连,如果有,权重为边的权重。在输入边信息时,输入的下标 i、j 分别对应的是邻接矩阵中的行和列。在遍历图时,用一个 `visited` 数组记录每个顶点是否被访问过,防止死循环。
用c语言遍历一个有邻接矩阵的有向无环图
可以使用深度优先搜索(DFS)或广度优先搜索(BFS)遍历有向无环图。这里以DFS为例,具体实现如下:
1. 定义一个数组visited,用于记录节点是否被访问过,初始值为0(未访问)
2. 从任意一个未被访问的节点开始遍历,遍历过程中将该节点标记为已访问(visited[i] = 1),然后遍历该节点的所有后继节点,对于每个后继节点j,如果visited[j]为0,则递归访问该节点
3. 遍历结束后,visited数组中所有元素都为1,则遍历完成
下面是代码实现:
```c
#include <stdio.h>
#define MAXN 100 // 最大节点数
int n; // 节点数
int g[MAXN][MAXN]; // 邻接矩阵
int visited[MAXN]; // 记录节点是否被访问过
void dfs(int i) {
visited[i] = 1; // 标记节点i为已访问
printf("%d ", i); // 打印节点i
for (int j = 0; j < n; j++) {
if (g[i][j] && !visited[j]) { // 如果节点j是节点i的后继节点,并且节点j未被访问过,则递归访问节点j
dfs(j);
}
}
}
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &g[i][j]); // 输入邻接矩阵
}
}
for (int i = 0; i < n; i++) {
if (!visited[i]) { // 如果节点i未被访问过,则从节点i开始遍历
dfs(i);
}
}
return 0;
}
```