当前位置: 首页 > 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.lryc.cn/news/594604.html

相关文章:

  • 第三章自定义检视面板_创建自定义编辑器类_如何自定义预览窗口(本章进度5/9)
  • C++基于libmodbus库实现modbus TCP/RTU通信
  • 个人中心产品设计指南:从信息展示到用户体验的细节把控
  • 第三章自定义检视面板_创建自定义编辑器类_编扩展默认组件的显示面板(本章进度3/9)
  • Jenkins 不同节点间文件传递:跨 Job 与 同 Job 的实现方法
  • 修复echarts由4.x升级5.x出现地图报错echarts/map/js/china.js未找到
  • 人形机器人CMU-ASAP算法理解
  • QGIS、ArcMap、ArcGIS Pro中的书签功能、场景裁剪
  • ruoyi-flowable-plus Excel 导入数据 Demo
  • 现在希望用git将本地文件test目录下的文件更新到远程仓库指定crawler目录下,命名相同的文件本地文件将其覆盖
  • 自动驾驶中各传感器的优缺点
  • 一个月掌握数据结构与算法:高效学习计划
  • uni-app 鸿蒙平台条件编译指南
  • vxe-table 通过配置 ajax 方式自动请求数据,适用于简单场景的列表
  • 网络基础1-11综合实验(eNSP):vlan/DHCP/Web/HTTP/动态PAT/静态NAT
  • MTSC2025参会感悟:大模型 + CV 重构全终端 UI 检测技术体系
  • C语言:深入理解指针(3)
  • cocos中实现3d人物角色头顶信息跟随功能,UI跟随3D/2D对象移动,例如昵称血条跟随人物移动
  • 【VASP】机器学习势概述
  • 智能合约安全 - 重入攻击 - 常见漏洞(第一篇)
  • taro微信小程序的tsconfig.json文件说明
  • Taro 本地存储 API 详解与实用指南
  • Typecho目录树插件开发:从后端解析到前端渲染全流程
  • 使用pymongo进行MongoDB的回收
  • Kali MSF渗透Windows 11电脑
  • Taro 路由相关 API 详解与实战
  • taro+pinia+小程序存储配置持久化
  • 微美全息(WIMI.US)聚焦多元哈希锁机制,为链上链下数据可信交互按下加速键
  • 快速入门SwiftUI
  • 【大模型】结构化提示词:让AI高效完成复杂任务的“编程语言”