数据结构实验六 图

目录

1. 图的广度优先遍历

2. 图的深度优先遍历


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;
}

猜你喜欢

转载自blog.csdn.net/timberman666/article/details/134543048