当前位置: 首页 > news >正文

【PTA数据结构 | C语言版】列出连通集

本专栏持续输出数据结构题目集,欢迎订阅。

文章目录

    • 题目
    • 代码

题目

给定一个有 n 个顶点和 m 条边的无向图,请用深度优先遍历(DFS)和广度优先遍历(BFS)分别列出其所有的连通集。假设顶点从 0 到 n−1 编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。

输入格式:
输入第 1 行给出 2 个整数 n (0<n≤10) 和 m,分别是图的顶点数和边数。随后 m 行,每行给出一条边的两个端点。每行中的数字之间用 1 空格分隔。

输出格式:
按照"{ v1 v2 … vk}"的格式,每行输出一个连通集。先输出 DFS 的结果,再输出 BFS 的结果。

输入样例:
8 6
0 7
0 1
2 0
4 1
2 4
3 5

输出样例:
{ 0 1 4 2 7 }
{ 3 5 }
{ 6 }
{ 0 1 2 7 4 }
{ 3 5 }
{ 6 }

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAX_VERTEX 10typedef struct Node {int vertex;struct Node* next;
} Node;typedef struct {Node* adj[MAX_VERTEX];int n;
} Graph;typedef struct {int data[MAX_VERTEX];int top;
} Stack;typedef struct {int data[MAX_VERTEX];int front, rear;
} Queue;// 函数声明
void initGraph(Graph* g, int n);
void addEdge(Graph* g, int src, int dest);
void DFS(Graph* g, int v, int visited[], int component[], int* count);
void BFS(Graph* g, int v, int visited[], int component[], int* count);
void initQueue(Queue* q);
int isQueueEmpty(Queue* q);
void enqueue(Queue* q, int v);
int dequeue(Queue* q);
void initStack(Stack* s);
int isStackEmpty(Stack* s);
void push(Stack* s, int v);
int pop(Stack* s);
int peek(Stack* s);int main() {int n, m;scanf("%d %d", &n, &m);Graph g;initGraph(&g, n);for (int i = 0; i < m; i++) {int src, dest;scanf("%d %d", &src, &dest);addEdge(&g, src, dest);}// DFS遍历int visited[MAX_VERTEX] = {0};for (int i = 0; i < n; i++) {if (!visited[i]) {int component[MAX_VERTEX];int count = 0;DFS(&g, i, visited, component, &count);printf("{");for (int j = 0; j < count; j++) {printf(" %d", component[j]);}printf(" }\n");}}// BFS遍历memset(visited, 0, sizeof(visited));for (int i = 0; i < n; i++) {if (!visited[i]) {int component[MAX_VERTEX];int count = 0;BFS(&g, i, visited, component, &count);printf("{");for (int j = 0; j < count; j++) {printf(" %d", component[j]);}printf(" }\n");}}return 0;
}// 初始化图
void initGraph(Graph* g, int n) {g->n = n;for (int i = 0; i < n; i++) {g->adj[i] = NULL;}
}// 添加无向边(按编号递增顺序插入)
void addEdge(Graph* g, int src, int dest) {// 添加src->dest的边(按递增顺序插入)Node* newNode = (Node*)malloc(sizeof(Node));newNode->vertex = dest;Node* prev = NULL;Node* curr = g->adj[src];while (curr != NULL && curr->vertex < dest) {prev = curr;curr = curr->next;}if (prev == NULL) {newNode->next = g->adj[src];g->adj[src] = newNode;} else {newNode->next = curr;prev->next = newNode;}// 添加dest->src的边(按递增顺序插入)newNode = (Node*)malloc(sizeof(Node));newNode->vertex = src;prev = NULL;curr = g->adj[dest];while (curr != NULL && curr->vertex < src) {prev = curr;curr = curr->next;}if (prev == NULL) {newNode->next = g->adj[dest];g->adj[dest] = newNode;} else {newNode->next = curr;prev->next = newNode;}
}// 初始化栈
void initStack(Stack* s) {s->top = -1;
}// 判断栈是否为空
int isStackEmpty(Stack* s) {return s->top == -1;
}// 入栈
void push(Stack* s, int v) {s->data[++(s->top)] = v;
}// 出栈
int pop(Stack* s) {return s->data[(s->top)--];
}// 获取栈顶元素
int peek(Stack* s) {return s->data[s->top];
}// 非递归深度优先搜索(避免栈溢出)
void DFS(Graph* g, int v, int visited[], int component[], int* count) {Stack stack;initStack(&stack);push(&stack, v);while (!isStackEmpty(&stack)) {int u = pop(&stack);if (!visited[u]) {visited[u] = 1;component[(*count)++] = u;// 逆序处理邻接点,确保按编号升序访问Node* temp = g->adj[u];Node* nodes[MAX_VERTEX];int nodeCount = 0;while (temp != NULL) {nodes[nodeCount++] = temp;temp = temp->next;}for (int i = nodeCount - 1; i >= 0; i--) {int adjVertex = nodes[i]->vertex;if (!visited[adjVertex]) {push(&stack, adjVertex);}}}}
}// 初始化队列
void initQueue(Queue* q) {q->front = q->rear = 0;
}// 判断队列是否为空
int isQueueEmpty(Queue* q) {return q->front == q->rear;
}// 入队
void enqueue(Queue* q, int v) {q->data[q->rear++] = v;
}// 出队
int dequeue(Queue* q) {return q->data[q->front++];
}// 广度优先搜索
void BFS(Graph* g, int v, int visited[], int component[], int* count) {Queue q;initQueue(&q);visited[v] = 1;enqueue(&q, v);component[(*count)++] = v;while (!isQueueEmpty(&q)) {int u = dequeue(&q);Node* temp = g->adj[u];while (temp != NULL) {int adjVertex = temp->vertex;if (!visited[adjVertex]) {visited[adjVertex] = 1;enqueue(&q, adjVertex);component[(*count)++] = adjVertex;}temp = temp->next;}}
}
http://www.dtcms.com/a/290320.html

相关文章:

  • 归并排序:优雅的分治排序算法(C语言实现)
  • 什么是商业智能BI数据分析的指标爆炸?
  • Leetcode 3624. Number of Integers With Popcount-Depth Equal to K II
  • nerf-2020
  • Python 列表操作—基础和进阶技巧
  • spring简单项目实战
  • H3C技术考核
  • ACE 插入元件
  • SQL审计、Archery实战记录
  • 深入解析Hadoop YARN:三层调度模型与资源管理机制
  • [Python]函数调用链中局部变量的内存影响:通过memory_profiler分析
  • AR巡检和传统巡检的区别
  • 在 Angular 应用程序中使用 Genkit 的完整指南
  • 基于ArcFace损失函数训练的人脸特征提取模型
  • IDEA 同时修改某个区域内所有相同变量名
  • AR技术:应急响应的加速利器
  • AR技术:石化行业培训的“游戏规则改变者”
  • Swap Face 使用遇到的问题
  • 识别PDF中的二维码
  • ASP.NET Core Web API 中集成 DeveloperSharp.RabbitMQ
  • (二)Unity3d-ROS联合仿真:运行Unity-Robotics-Hub
  • java解析nc气象数据
  • HOT100——图篇Leetcode207. 课程表
  • Trae开发uni-app+Vue3+TS项目飘红踩坑
  • Cosmos
  • PostgreSQL 终端命令详解及实际应用案例
  • 【LINUX操作系统】搭建web网络服务器
  • Softhub软件下载站实战开发(二十):Docker部署全攻略
  • 前后端分离项目进阶1---前端
  • 对称加密技术详解:原理、算法与实际应用