用c语言写一个代码,可以运行的,需求如下 1.选择邻接矩阵或邻接表其中一种对图进行存储; 2.实现图的广度优先和深度优先两种遍历方法; 3.实现图的最小生成树算法,Prim或kruskal算法二者均需实现
时间: 2024-03-14 16:43:23 浏览: 64
好的,以下是符合您需求的 C 语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_VERTEX_NUM 100 // 最大顶点数
#define INFINITY 65535 // 定义无穷大
// 定义边结构体
typedef struct EdgeNode {
int adjvex; // 邻接点下标
int weight; // 权值
struct EdgeNode *next; // 指向下一条边的指针
} EdgeNode;
// 定义顶点结构体
typedef struct {
char data; // 顶点信息
EdgeNode *first_edge; // 指向第一条边的指针
} VertexNode;
// 定义图结构体
typedef struct {
VertexNode vexs[MAX_VERTEX_NUM]; // 顶点数组
int vex_num, edge_num; // 顶点数和边数
bool visited[MAX_VERTEX_NUM]; // 标记顶点是否被访问过
} Graph;
// 初始化图
void init_graph(Graph *G) {
G->vex_num = 0;
G->edge_num = 0;
for (int i = 0; i < MAX_VERTEX_NUM; i++) {
G->visited[i] = false;
G->vexs[i].first_edge = NULL;
}
}
// 获取顶点下标
int get_vertex_index(Graph *G, char v) {
for (int i = 0; i < G->vex_num; i++) {
if (G->vexs[i].data == v) {
return i;
}
}
return -1;
}
// 添加顶点
void add_vertex(Graph *G, char v) {
G->vexs[G->vex_num].data = v;
G->vexs[G->vex_num].first_edge = NULL;
G->vex_num++;
}
// 添加边
void add_edge(Graph *G, char v1, char v2, int weight) {
int i = get_vertex_index(G, v1);
int j = get_vertex_index(G, v2);
EdgeNode *e = (EdgeNode *) malloc(sizeof(EdgeNode));
e->adjvex = j;
e->weight = weight;
e->next = G->vexs[i].first_edge;
G->vexs[i].first_edge = e;
e = (EdgeNode *) malloc(sizeof(EdgeNode));
e->adjvex = i;
e->weight = weight;
e->next = G->vexs[j].first_edge;
G->vexs[j].first_edge = e;
G->edge_num++;
}
// 深度优先遍历
void dfs(Graph *G, int v) {
printf("%c ", G->vexs[v].data);
G->visited[v] = true;
EdgeNode *e = G->vexs[v].first_edge;
while (e) {
int j = e->adjvex;
if (!G->visited[j]) {
dfs(G, j);
}
e = e->next;
}
}
// 广度优先遍历
void bfs(Graph *G, int v) {
int queue[MAX_VERTEX_NUM], front = 0, rear = 0;
printf("%c ", G->vexs[v].data);
G->visited[v] = true;
queue[rear++] = v;
while (front != rear) {
int i = queue[front++];
EdgeNode *e = G->vexs[i].first_edge;
while (e) {
int j = e->adjvex;
if (!G->visited[j]) {
printf("%c ", G->vexs[j].data);
G->visited[j] = true;
queue[rear++] = j;
}
e = e->next;
}
}
}
// Prim算法
void prim(Graph *G, int v) {
int dist[MAX_VERTEX_NUM], prev[MAX_VERTEX_NUM];
for (int i = 0; i < G->vex_num; i++) {
dist[i] = INFINITY;
prev[i] = -1;
}
dist[v] = 0;
for (int i = 0; i < G->vex_num; i++) {
int min_dist = INFINITY, u = -1;
for (int j = 0; j < G->vex_num; j++) {
if (!G->visited[j] && dist[j] < min_dist) {
min_dist = dist[j];
u = j;
}
}
if (u == -1) {
return;
}
G->visited[u] = true;
EdgeNode *e = G->vexs[u].first_edge;
while (e) {
int j = e->adjvex;
if (!G->visited[j] && e->weight < dist[j]) {
dist[j] = e->weight;
prev[j] = u;
}
e = e->next;
}
}
printf("Prim最小生成树:\n");
for (int i = 0; i < G->vex_num; i++) {
if (prev[i] != -1) {
printf("%c - %c\n", G->vexs[prev[i]].data, G->vexs[i].data);
}
}
}
// Kruskal算法
void kruskal(Graph *G) {
int parent[MAX_VERTEX_NUM], rank[MAX_VERTEX_NUM];
for (int i = 0; i < G->vex_num; i++) {
parent[i] = i;
rank[i] = 0;
}
EdgeNode *edges[MAX_VERTEX_NUM * (MAX_VERTEX_NUM - 1) / 2];
int k = 0;
for (int i = 0; i < G->vex_num; i++) {
EdgeNode *e = G->vexs[i].first_edge;
while (e) {
if (i < e->adjvex) {
edges[k++] = e;
}
e = e->next;
}
}
for (int i = 0; i < k; i++) {
for (int j = i + 1; j < k; j++) {
if (edges[i]->weight > edges[j]->weight) {
EdgeNode *temp = edges[i];
edges[i] = edges[j];
edges[j] = temp;
}
}
}
printf("Kruskal最小生成树:\n");
for (int i = 0; i < k; i++) {
int u = edges[i]->adjvex;
int v = get_vertex_index(G, edges[i]->data);
while (u != parent[u]) {
u = parent[u];
}
while (v != parent[v]) {
v = parent[v];
}
if (u != v) {
printf("%c - %c\n", edges[i]->data, G->vexs[u].data);
if (rank[u] > rank[v]) {
parent[v] = u;
} else if (rank[u] < rank[v]) {
parent[u] = v;
} else {
parent[v] = u;
rank[u]++;
}
}
}
}
int main() {
Graph G;
init_graph(&G);
add_vertex(&G, 'A');
add_vertex(&G, 'B');
add_vertex(&G, 'C');
add_vertex(&G, 'D');
add_vertex(&G, 'E');
add_edge(&G, 'A', 'B', 6);
add_edge(&G, 'A', 'D', 1);
add_edge(&G, 'B', 'C', 5);
add_edge(&G, 'B', 'D', 2);
add_edge(&G, 'B', 'E', 2);
add_edge(&G, 'C', 'E', 5);
add_edge(&G, 'D', 'E', 1);
printf("深度优先遍历结果:");
dfs(&G, 0);
printf("\n");
for (int i = 0; i < G.vex_num; i++) {
G.visited[i] = false;
}
printf("广度优先遍历结果:");
bfs(&G, 0);
printf("\n");
for (int i = 0; i < G.vex_num; i++) {
G.visited[i] = false;
}
prim(&G, 0);
kruskal(&G);
return 0;
}
```
以上代码实现了邻接表存储图,包括了深度优先遍历、广度优先遍历、Prim算法和Kruskal算法。您只需要在 main 函数中调用相应的函数即可。
阅读全文