目录
1. 图的广度优先遍历
【问题描述】
建立邻接表结构无向图,输出给定起点的图的广度优先遍历序列。由于广度优先遍历的节点序列是不唯一的,为了使得输出具有唯一的结果,我们约定以表头插入法构造邻接表。
【输入形式】
输入第一行给出三个正整数,分别表示无向图的节点数N(1<N≤10)、边数M(≤50)和探索起始节点编号S(节点从1到N编号)。
随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号。
【输出形式】
输出从S开始的无向图的先广搜索序列。如果为非连通图,换行输出所有连通分量。
【样例输入】
6 8 2
1 2
2 3
3 4
4 5
5 6
6 4
3 6
1 5
【样例输出】
2 3 1 6 4 5
【样例输入】
8 6 1
1 8
1 2
3 1
5 2
3 5
4 6
【样例输出】
1 3 2 8 5
4 6
7
【样例说明】
【评分标准】
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int vertex;
struct Node* next;
} Node;
typedef struct Vertex {
Node* head;
} Vertex;
void BFS(Vertex* graph, int start, int numVertices, int* visited) {
int queue[numVertices];
int front = 0, rear = 0;
Node* node;
visited[start] = 1;
queue[rear++] = start;
while (front < rear) {
int current = queue[front++];
printf("%d ", current + 1);
node = graph[current].head;
while (node != NULL) {
if (!visited[node->vertex]) {
visited[node->vertex] = 1;
queue[rear++] = node->vertex;
}
node = node->next;
}
}
}
int main() {
int numVertices, numEdges, start;
scanf("%d %d %d", &numVertices, &numEdges, &start);
Vertex* graph = (Vertex*)malloc(numVertices * sizeof(Vertex));
int visited[numVertices];
for (int i = 0; i < numVertices; i++) {
graph[i].head = NULL;
visited[i] = 0;
}
for (int i = 0; i < numEdges; i++) {
int v1, v2;
scanf("%d %d", &v1, &v2);
v1--;
v2--;
Node* newNode1 = (Node*)malloc(sizeof(Node));
newNode1->vertex = v2;
newNode1->next = graph[v1].head;
graph[v1].head = newNode1;
Node* newNode2 = (Node*)malloc(sizeof(Node));
newNode2->vertex = v1;
newNode2->next = graph[v2].head;
graph[v2].head = newNode2;
}
BFS(graph, start - 1, numVertices, visited);
for (int i = 0; i < numVertices; i++) {
if (!visited[i]) {
printf("\n");
BFS(graph, i, numVertices, visited);
}
}
for (int i = 0; i < numVertices; i++) {
Node* current = graph[i].head;
while (current != NULL) {
Node* temp = current;
current = current->next;
free(temp);
}
}
free(graph);
return 0;
}
2. 图的深度优先遍历
【问题描述】
给定一个无向图,输出指定顶点出发的深度优先遍历序列。在深度优先遍历的过程中,如果同时出现多个待访问的顶点,则优先选择编号最小的一个进行访问.
【输入形式】
第一行输入三个正整数,分别表示无向图的顶点数N(1≤N≤1000,顶点从1到N编号)、边数M和指定起点编号S。接下来的M行对应M条边,每行给出两个正整数,分别是该条边的端点编号。
【输出形式】
输出从S开始的深度优先遍历序列,用一个空格隔开,最后也含有一个空格。如果从S出发无法遍历到图中的所有顶点,换行输出图中所有联通分量。
【样例输入】
5 4 2
1 2
2 3
5 2
1 3
【样例输出】
2 1 3 5
4
【样例输入】
4 3 1 1 2 2 3 3 1
【样例输出】
1 2 3
4
【样例说明】
【评分标准】
#include <stdio.h>
#include <stdlib.h>
#define MAX 1000
int graph[MAX][MAX];
int visited[MAX];
int n;
void DFS(int v) {
printf("%d ", v);
visited[v] = 1;
for (int i = 1; i <= n; i++) {
if (graph[v][i] && !visited[i]) {
DFS(i);
}
}
}
int main() {
int m, s;
scanf("%d %d %d", &n, &m, &s);
for (int i = 0; i < m; i++) {
int a, b;
scanf("%d %d", &a, &b);
graph[a][b] = 1;
graph[b][a] = 1;
}
DFS(s);
int flag = 0;
for (int i = 1; i <= n; i++) {
if (!visited[i]) {
flag = 1;
break;
}
}
if (flag) {
printf("\n");
for (int i = 1; i <= n; i++) {
if (!visited[i]) {
DFS(i);
printf("\n");
}
}
}
return 0;
}