图的基本操作与实现,要求用邻接表存储结构,实现对图11-3所示的有向带权网络G的操作。 ⑴ 输入含n(1≤n≤100)个顶点(用字符表示顶点)和e条边; ⑵ 求每个顶点的出度和入度,输出结果; ⑶ 指定任意顶点x为初始顶点,对图G作DFS遍历,输出DFS顶点序列; ⑷ 指定任意顶点x为初始顶点,对图G作BFS遍历,输出BFS顶点序列; ⑸ 输入顶点x,查找图G:若存在含x的顶点,则删除该结点及与之相关联的边,并作DFS遍历;否则输出信息“无x”; ⑹ 判断图G是否是连通图,输出信息“YES”/“NO”; ⑺ 根据图G的邻接表创建图G的邻接矩阵,即复制图G。 ⑻ 找出该图的一棵最小生成树。

时间: 2024-03-11 08:46:58 浏览: 20
邻接表存储结构定义: ```c typedef char VertexType; // 顶点类型 typedef int EdgeType; // 边权值类型 // 边表结点 typedef struct EdgeNode { int adjvex; // 邻接点编号 EdgeType weight; // 边权值 struct EdgeNode *next; // 指向下一个邻接点 } EdgeNode; // 顶点表结点 typedef struct VertexNode { VertexType data; // 顶点数据 EdgeNode *firstEdge; // 指向第一个邻接点 } VertexNode, AdjList[MAXVEX]; // 邻接表存储结构 typedef struct { AdjList adjList; // 邻接表 int numVertexes, numEdges; // 顶点数和边数 } GraphAdjList; ``` 辅助函数: ```c // 返回顶点在邻接表中的位置 int LocateVex(GraphAdjList G, VertexType v) { for (int i = 0; i < G.numVertexes; i++) { if (G.adjList[i].data == v) { return i; } } return -1; } // 深度优先搜索遍历 void DFS(GraphAdjList G, int i, bool visited[]) { visited[i] = true; printf("%c", G.adjList[i].data); EdgeNode *p = G.adjList[i].firstEdge; while (p) { if (!visited[p->adjvex]) { DFS(G, p->adjvex, visited); } p = p->next; } } // 广度优先搜索遍历 void BFS(GraphAdjList G, int i, bool visited[]) { int queue[MAXVEX], front = 0, rear = 0; printf("%c", G.adjList[i].data); visited[i] = true; queue[rear++] = i; while (front != rear) { int j = queue[front++]; EdgeNode *p = G.adjList[j].firstEdge; while (p) { if (!visited[p->adjvex]) { printf("%c", G.adjList[p->adjvex].data); visited[p->adjvex] = true; queue[rear++] = p->adjvex; } p = p->next; } } } // 删除结点及其相关联的边 void DeleteVex(GraphAdjList *G, VertexType v) { int i = LocateVex(*G, v); if (i == -1) { printf("无%c\n", v); return; } EdgeNode *p = G->adjList[i].firstEdge; while (p) { int j = p->adjvex; EdgeNode *q = G->adjList[j].firstEdge, *r = NULL; while (q) { if (q->adjvex == i) { if (r == NULL) { G->adjList[j].firstEdge = q->next; } else { r->next = q->next; } free(q); G->numEdges--; break; } r = q; q = q->next; } p = p->next; } G->numVertexes--; for (int j = i; j < G->numVertexes; j++) { G->adjList[j] = G->adjList[j+1]; } for (int j = 0; j < G->numVertexes; j++) { EdgeNode *p = G->adjList[j].firstEdge; while (p) { if (p->adjvex > i) { p->adjvex--; } p = p->next; } } } // 连通性检查 bool DFS2(GraphAdjList G, int i, bool visited[]) { visited[i] = true; EdgeNode *p = G.adjList[i].firstEdge; while (p) { if (!visited[p->adjvex]) { DFS2(G, p->adjvex, visited); } p = p->next; } return true; } bool IsConnected(GraphAdjList G) { bool visited[MAXVEX] = { false }; DFS2(G, 0, visited); for (int i = 0; i < G.numVertexes; i++) { if (!visited[i]) { return false; } } return true; } // 边的最小堆 typedef struct { int u, v; // 边的两个顶点 EdgeType w; // 边的权值 } Edge; typedef struct { Edge data[MAXEDGE]; int size; } MinHeap; void Insert(MinHeap *H, Edge e) { H->data[++H->size] = e; int i = H->size; while (i > 1 && H->data[i].w < H->data[i/2].w) { Edge tmp = H->data[i]; H->data[i] = H->data[i/2]; H->data[i/2] = tmp; i /= 2; } } Edge Delete(MinHeap *H) { Edge ret = H->data[1]; H->data[1] = H->data[H->size--]; int i = 1; while (i*2 <= H->size) { int child = i*2; if (child < H->size && H->data[child+1].w < H->data[child].w) { child++; } if (H->data[child].w < H->data[i].w) { Edge tmp = H->data[child]; H->data[child] = H->data[i]; H->data[i] = tmp; i = child; } else { break; } } return ret; } ``` 操作实现: ⑴ 输入含n(1≤n≤100)个顶点(用字符表示顶点)和e条边; ```c void CreateGraph(GraphAdjList *G) { printf("输入顶点数和边数:"); scanf("%d%d", &G->numVertexes, &G->numEdges); getchar(); // 读取多余的换行符 printf("输入顶点:"); for (int i = 0; i < G->numVertexes; i++) { scanf("%c", &G->adjList[i].data); G->adjList[i].firstEdge = NULL; } getchar(); // 读取多余的换行符 printf("输入边(<vi,vj,w>):"); for (int k = 0; k < G->numEdges; k++) { VertexType vi, vj; EdgeType w; scanf("<%c,%c,%d>", &vi, &vj, &w); getchar(); // 读取多余的换行符 int i = LocateVex(*G, vi), j = LocateVex(*G, vj); EdgeNode *e = (EdgeNode *)malloc(sizeof(EdgeNode)); e->adjvex = j; e->weight = w; e->next = G->adjList[i].firstEdge; G->adjList[i].firstEdge = e; } } ``` ⑵ 求每个顶点的出度和入度,输出结果; ```c void PrintInAndOutDegree(GraphAdjList G) { int inDegree[MAXVEX] = { 0 }, outDegree[MAXVEX] = { 0 }; for (int i = 0; i < G.numVertexes; i++) { EdgeNode *p = G.adjList[i].firstEdge; while (p) { outDegree[i]++; inDegree[p->adjvex]++; p = p->next; } } printf("顶点 出度 入度\n"); for (int i = 0; i < G.numVertexes; i++) { printf("%c %d %d\n", G.adjList[i].data, outDegree[i], inDegree[i]); } } ``` ⑶ 指定任意顶点x为初始顶点,对图G作DFS遍历,输出DFS顶点序列; ```c void DFSTraverse(GraphAdjList G, VertexType v) { bool visited[MAXVEX] = { false }; int i = LocateVex(G, v); DFS(G, i, visited); } ``` ⑷ 指定任意顶点x为初始顶点,对图G作BFS遍历,输出BFS顶点序列; ```c void BFSTraverse(GraphAdjList G, VertexType v) { bool visited[MAXVEX] = { false }; int i = LocateVex(G, v); BFS(G, i, visited); } ``` ⑸ 输入顶点x,查找图G:若存在含x的顶点,则删除该结点及与之相关联的边,并作DFS遍历;否则输出信息“无x”; ```c void DeleteVexAndDFS(GraphAdjList *G, VertexType v) { DeleteVex(G, v); bool visited[MAXVEX] = { false }; if (LocateVex(*G, v) != -1) { printf("DFS遍历序列:"); int i = 0; while (visited[i]) i++; DFS(*G, i, visited); } } ``` ⑹ 判断图G是否是连通图,输出信息“YES”/“NO”; ```c void PrintConnected(GraphAdjList G) { if (IsConnected(G)) { printf("YES\n"); } else { printf("NO\n"); } } ``` ⑺ 根据图G的邻接表创建图G的邻接矩阵,即复制图G。 ```c void CreateMGraph(GraphAdjList G, EdgeType (*matrix)[MAXVEX]) { for (int i = 0; i < G.numVertexes; i++) { for (int j = 0; j < G.numVertexes; j++) { matrix[i][j] = INFINITY; } EdgeNode *p = G.adjList[i].firstEdge; while (p) { matrix[i][p->adjvex] = p->weight; p = p->next; } } } ``` ⑻ 找出该图的一棵最小生成树。 ```c void MiniSpanTree_Kruskal(GraphAdjList G) { Edge edges[MAXEDGE]; int k = 0; for (int i = 0; i < G.numVertexes; i++) { EdgeNode *p = G.adjList[i].firstEdge; while (p) { if (i < p->adjvex) { edges[k].u = i; edges[k].v = p->adjvex; edges[k].w = p->weight; k++; } p = p->next; } } MinHeap H = { 0 }; for (int i = 0; i < k; i++) { Insert(&H, edges[i]); } int parent[MAXVEX]; for (int i = 0; i < G.numVertexes; i++) { parent[i] = i; } int count = 0; while (count < G.numVertexes-1 && H.size > 0) { Edge e = Delete(&H); int u = e.u, v = e.v; while (parent[u] != u) { u = parent[u]; } while (parent[v] != v) { v = parent[v]; } if (u != v) { printf("%c-%c ", G.adjList[e.u].data, G.adjList[e.v].data); parent[v] = u; count++; } } } ``` 完整代码:

相关推荐

最新推荐

recommend-type

广州大学 数据结构实验报告 实验三 图的操作与实现

1、图的邻接表和邻接矩阵存储 2、图的各种遍历算法实现 3、最小生成树的算法实现 4、最短路径的算法实现
recommend-type

邻接表或者邻接矩阵为存储结构实现连通无向图的深度优先和广度优先遍历

基本要求:以邻接表或者邻接矩阵为存储结构,实现连通无向图的深度优先和广度优先遍历。以用户指定的结点为起点,分别输出每种遍历下的结点访问序列和相应生成树的边集。测试数据:教科书p168图7.13(a)。
recommend-type

C语言实现图的邻接矩阵存储操作

主要为大家详细介绍了C语言实现图的邻接矩阵存储操作,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
recommend-type

实现带权图的邻接表存储+图的遍历算法

带权图的临接表存储程序代码+详细注释,实现图的深度优先搜索和广度优先搜索
recommend-type

组成原理课程实验:MIPS 流水线CPU、实现36条指令、转发、冒险检测-内含源码和说明书.zip

组成原理课程实验:MIPS 流水线CPU、实现36条指令、转发、冒险检测-内含源码和说明书.zip
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

用 Python 画一个可以动的爱心

好的,我可以帮助您使用Python来绘制一个动态的爱心。您可以使用turtle库来实现。以下是实现代码: ```python import turtle import math # 设置画布和画笔 canvas = turtle.Screen() canvas.bgcolor("black") pencil = turtle.Turtle() pencil.speed(0) pencil.color("red", "pink") pencil.pensize(3) # 定义爱心函数 def draw_love(heart_size, x_offset=0, y_offset=0):
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。