帮我用C语言写一个由以下条件的代码(1) 由给定的顶点和边的信息构造图的邻接矩阵存储; (2) 对该图进行深度优先搜索,输出搜索得到的结点序列; (3) 以邻接表作存储结构,用克鲁斯卡尔算法构造最小生成树。
时间: 2024-03-11 13:44:12 浏览: 83
好的,下面是使用C语言实现的代码,满足以下条件:
1. 由给定的顶点和边的信息构造图的邻接矩阵存储
2. 对该图进行深度优先搜索,输出搜索得到的结点序列
3. 以邻接表作存储结构,用克鲁斯卡尔算法构造最小生成树
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_VERTEX_NUM 20 // 最大顶点数
#define MAX_EDGE_NUM 50 // 最大边数
typedef struct {
int vertex[MAX_VERTEX_NUM]; // 存储顶点
int edge[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 存储边
int vertexNum; // 顶点的数量
int edgeNum; // 边的数量
} Graph;
typedef struct {
int u, v; // 边的两个顶点
int weight; // 边权值
} Edge;
typedef struct {
int vertex; // 顶点编号
int next; // 下一个邻接点在数组中的位置
int weight; // 边的权值
} Node;
typedef struct {
Node edge[MAX_EDGE_NUM * 2]; // 存储边
int head[MAX_VERTEX_NUM]; // 存储每个顶点的第一个邻接点在数组中的位置
int vertexNum; // 顶点的数量
int edgeNum; // 边的数量
} GraphList;
bool visited[MAX_VERTEX_NUM]; // 记录每个顶点是否被访问过
/* 深度优先搜索 */
void DFS(Graph* graph, int v) {
visited[v] = true; // 标记顶点v已被访问
printf("%d ", v); // 输出顶点v的编号
for (int i = 0; i < graph->vertexNum; i++) {
if (graph->edge[v][i] && !visited[i]) { // 如果顶点v和顶点i之间有边,并且顶点i没有被访问过
DFS(graph, i); // 递归访问顶点i
}
}
}
/* 用邻接表存储图 */
void initGraphList(GraphList* graph, int vertexNum) {
graph->vertexNum = vertexNum;
graph->edgeNum = 0;
for (int i = 0; i < vertexNum; i++) {
graph->head[i] = -1; // 将每个顶点的第一个邻接点初始化为-1
}
}
/* 添加一条边 */
void addEdge(GraphList* graph, int u, int v, int weight) {
graph->edge[graph->edgeNum].vertex = v;
graph->edge[graph->edgeNum].weight = weight;
graph->edge[graph->edgeNum].next = graph->head[u];
graph->head[u] = graph->edgeNum++;
}
/* 查找顶点所在的集合 */
int find(int parent[], int i) {
while (parent[i] != i) {
i = parent[i];
}
return i;
}
/* 合并两个集合 */
void unionSet(int parent[], int x, int y) {
int xRoot = find(parent, x);
int yRoot = find(parent, y);
parent[xRoot] = yRoot;
}
/* 按边权值从小到大排序 */
int cmp(const void* a, const void* b) {
return ((Edge*)a)->weight - ((Edge*)b)->weight;
}
/* 构造最小生成树 */
void kruskal(GraphList* graph) {
int parent[MAX_VERTEX_NUM];
for (int i = 0; i < graph->vertexNum; i++) {
parent[i] = i;
}
Edge edges[MAX_EDGE_NUM];
int edgeNum = 0;
for (int i = 0; i < graph->vertexNum; i++) {
for (int j = graph->head[i]; j != -1; j = graph->edge[j].next) {
int v = graph->edge[j].vertex;
int weight = graph->edge[j].weight;
edges[edgeNum].u = i;
edges[edgeNum].v = v;
edges[edgeNum].weight = weight;
edgeNum++;
}
}
qsort(edges, edgeNum, sizeof(Edge), cmp);
for (int i = 0; i < edgeNum; i++) {
int u = edges[i].u;
int v = edges[i].v;
int weight = edges[i].weight;
int uRoot = find(parent, u);
int vRoot = find(parent, v);
if (uRoot != vRoot) {
printf("Edge %d:(%d, %d) weight: %d\n", i, u, v, weight);
unionSet(parent, u, v);
}
}
}
int main() {
Graph graph;
GraphList graphList;
int vertexNum = 6;
graph.vertexNum = vertexNum;
graph.edgeNum = 9;
initGraphList(&graphList, vertexNum);
int edges[9][3] = {
{0, 1, 1},
{0, 2, 6},
{0, 3, 5},
{1, 2, 3},
{1, 4, 2},
{2, 3, 4},
{2, 4, 7},
{3, 5, 9},
{4, 5, 8}
};
for (int i = 0; i < graph.edgeNum; i++) {
int u = edges[i][0];
int v = edges[i][1];
int weight = edges[i][2];
graph.edge[u][v] = weight;
graph.edge[v][u] = weight;
addEdge(&graphList, u, v, weight);
addEdge(&graphList, v, u, weight);
}
printf("邻接矩阵:\n");
for (int i = 0; i < vertexNum; i++) {
for (int j = 0; j < vertexNum; j++) {
printf("%d ", graph.edge[i][j]);
}
printf("\n");
}
printf("深度优先搜索结果:\n");
DFS(&graph, 0);
printf("\n");
printf("最小生成树:\n");
kruskal(&graphList);
return 0;
}
```
这份代码实现了三个功能:
1. 由给定的顶点和边的信息构造图的邻接矩阵存储;
2. 对该图进行深度优先搜索,输出搜索得到的结点序列;
3. 以邻接表作存储结构,用克鲁斯卡尔算法构造最小生成树。
具体实现细节见代码注释。
阅读全文