本次题目为数据结构课设:
(1)数据准备
按照图 1 所示城市交通网(图中边上的权值表示城市之间的距离),将数据保存在文本文件中,文件名为:“班名+序号_Graph.txt”.
用以下格式存储:
11 11
北京 天津 西安 郑州 徐州 上海 成都 武汉 株洲 南昌 广州
北京 天津 137
北京 郑州 695
天津 徐州 674
徐州 上海 651
徐州 郑州 349
郑州 西安 511
西安 成都 842
郑州 武汉 534
株洲 武汉 411
株洲 南昌 367
株洲 广州 409
(2)功能要求
用图的邻接矩阵的表示方法存储图 1 所示的城市交通信息网。在主函数中设计功能菜
单,利用菜单调用各个函数,分别完成以下各功能:
①设计在相应存储结构(邻接矩阵或邻接表)下的图的类型声明。
②根据图 1 所示交通网,创建无向带权图。读取交通信息:从指定位置文件中读取顶
点和边的信息,保存到邻接矩阵中,并输出无向带权图。
③交通信息维护。A、城市信息维护:可以添加、删除、修改城市信息;B、连通信息
维护:可以添加、删除、修改城市之间的连通信息。(注:为了操作简便,在添加和删除城市信息时,只要求在存储城市信息的一维数组的末尾进行)
④图的遍历。输入某个起点,进行深度优先遍历和广度优先遍历,输出其遍历序列。
⑤求最小生成树。使用 Prim 算法或 Kurskal 算法构造一棵最小生成树,保证所有城市
连通且路程最短。
⑥使用 Floyd 算法求任意两个城市之间的最短路径。(选做)
⑦使用 Dijkstra 算法求源点(第一个城市)到其他各城市之间的最短路径。(选做)
以下为我自己写的程序,仅展示算法部分供借鉴:
#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
using namespace std;
#define MAX 100//最大顶点数
#define INFINITY 32767 //表示∞
#define TRUE 1
#define FALSE 0
typedef int Bool;
Bool visited[MAX];
typedef struct
{//邻接矩阵结构
int n,e;//顶点数n,边数e
char vexs[MAX][MAX];//顶点数组
int edges[MAX][MAX];//边的邻接矩阵
}MGraph;
void CreateMGraph(MGraph *G){//创建图
FILE *fp=fopen("E:\\code\\sjjg\\计科Z62103班04_Graph.txt","r");
if(fp==NULL){
printf("读取文件失败!");
fclose (fp);
}
char ch1[MAX],ch2[MAX];
fscanf(fp,"%d",&G->n);
fscanf(fp,"%d",&G->e);
for(int i=0;i<G->n;i++){
fscanf(fp,"%s",G->vexs[i]);
}
for(int i=0;i<G->n;i++){//邻接矩阵元素置∞
for(int j=0;j<G->n;j++){
G->edges[i][j]=INFINITY;
}
}
for(int i=0;i<G->e;i++){
fscanf(fp,"%s",ch1);
fscanf(fp,"%s",ch2);
for(int j=0;j<G->n;j++){
for(int k=0;k<G->n;k++){
if(strcmp(ch1,G->vexs[j])==0&&strcmp(ch2,G->vexs[k])==0){
fscanf(fp,"%d",&(G->edges[j][k]));
G->edges[k][j]=G->edges[j][k];
}
}
}
}
fclose (fp);
}
void DispMGraph(MGraph *G){//图的邻接矩阵输出函数
for(int i=0;i<G->n;i++){
for(int j=0;j<G->n;j++)
printf("%5d",G->edges[i][j]);
printf("\n");
}
}
void AddCity(MGraph *G){//添加城市信息
printf("请输入想要加入的城市:");
scanf("%s",G->vexs[G->n]);
G->n++;
for(int i=0;i<G->n;i++){//邻接矩阵元素置0
for(int j=0;j<G->n;j++){
if(i==G->n-1||j==G->n-1){
G->edges[i][j]=INFINITY;
}
}
}
for(int i=0;i<G->n;i++){
printf("%s ",G->vexs[i]);
}
}
void AlterCity(MGraph *G){//修改城市信息
printf("请输入想要修改的城市信息:");
char ch1[MAX];
scanf("%s",ch1);
for(int i=0;i<G->n;i++){
if(strcmp(ch1,G->vexs[i])==0){
printf("请输入修改后的城市信息:");
scanf("%s",ch1);
memcpy(G->vexs[i],ch1,MAX);
}
}
for(int i=0;i<G->n;i++){
printf("%s ",G->vexs[i]);
}
}
void DeleteCity(MGraph *G){//删除城市信息
printf("请输入想要删除的城市信息:");
char ch1[MAX];
scanf("%s",ch1);
for(int i=0;i<G->n;i++){
if(strcmp(ch1,G->vexs[i])==0){
for(int j=i;j<G->n;j++){
memcpy(G->vexs[j],G->vexs[j+1],MAX);
}
G->n--;
}
}
for(int i=0;i<G->n;i++){
printf("%s ",G->vexs[i]);
}
}
void AddTraffic(MGraph *G){//添加交通信息
printf("请输入想要加入的交通信息(两个城市名):");
char ch1[MAX],ch2[MAX];
scanf("%s",ch1);
scanf("%s",ch2);
for(int j=0;j<G->n;j++){
for(int k=0;k<G->n;k++){
if(strcmp(ch1,G->vexs[j])==0&&strcmp(ch2,G->vexs[k])==0){
if(G->edges[j][k]==INFINITY&&G->edges[k][j]==INFINITY){
printf("请输入两个城市之间的距离:");
scanf("%d",&(G->edges[j][k]));
G->edges[k][j]=G->edges[j][k];
G->e++;
}
else
printf("两个城市之间存在交通信息!\n");
}
}
}
for(int i=0;i<G->n;i++){
for(int j=0;j<G->n;j++)
printf("%5d",G->edges[i][j]);
printf("\n");
}
}
void AlterTraffic(MGraph *G){//修改交通信息
printf("请输入想要修改的交通信息(两个城市名):");
char ch1[MAX],ch2[MAX];
scanf("%s",ch1);
scanf("%s",ch2);
for(int j=0;j<G->n;j++){
for(int k=0;k<G->n;k++){
if(strcmp(ch1,G->vexs[j])==0&&strcmp(ch2,G->vexs[k])==0){
if(G->edges[j][k]!=0&&G->edges[k][j]!=0){
printf("请输入两个城市之间的距离:");
scanf("%d",&(G->edges[j][k]));
G->edges[k][j]=G->edges[j][k];
}
else
printf("两个城市之间不存在交通信息!");
}
}
}
for(int i=0;i<G->n;i++){
for(int j=0;j<G->n;j++)
printf("%5d",G->edges[i][j]);
printf("\n");
}
}
void DeleteTraffic(MGraph *G){//删除交通信息
printf("请输入想要删除的交通信息(两个城市名):");
char ch1[MAX],ch2[MAX];
scanf("%s",ch1);
scanf("%s",ch2);
for(int j=0;j<G->n;j++){
for(int k=0;k<G->n;k++){
if(strcmp(ch1,G->vexs[j])==0&&strcmp(ch2,G->vexs[k])==0){
if(G->edges[j][k]!=0&&G->edges[k][j]!=0){
G->edges[j][k]=INFINITY;
G->edges[k][j]=G->edges[j][k];
}
else
printf("两个城市之间不存在交通信息!");
}
}
}
for(int i=0;i<G->n;i++){
for(int j=0;j<G->n;j++)
printf("%5d",G->edges[i][j]);
printf("\n");
}
}
//图的深度优先遍历
void DFS(MGraph *G, int i){
int j;
visited[i]=TRUE;
printf("%s",G->vexs[i]);
for(j=0;j<G->n;++j){
if (G->edges[i][j]!=INFINITY && !visited[j])
DFS(G, j);
}
}
void DFSTraverse(MGraph *G){
char ch1[MAX];
for(int i=0;i<G->n;++i)
visited[i]=FALSE;
printf("请输入起始城市名:");
scanf("%s",ch1);
for(int i=0;i<G->n;++i){
if(strcmp(ch1,G->vexs[i])==0){
DFS(G,i);
for(int i=0;i<G->n;++i)
if (!visited[i])
DFS(G,i);
}
}
}
//广度优先遍历需要的循环队列
typedef struct {
int data[MAX];
int front, rear;
}Queue;
void InitQueue(Queue *Q){//初始化
Q->front = Q->rear = 0;
}
void EnQueue(Queue *Q, int e){//入队
if ((Q->rear+1)%MAX == Q->front)
return ;
Q->data[Q->rear] = e;
Q->rear = (Q->rear+1)%MAX;
}
Bool QueueEmpty(Queue *Q){//判空
if (Q->front == Q->rear)
return TRUE;
else
return FALSE;
}
void DeQueue(Queue *Q, int *e){//出队
if (Q->front == Q->rear)
return ;
*e = Q->data[Q->front];
Q->front = (Q->front+1)%MAX;
}
//图的广度优先遍历
void BFSTraverse(MGraph *G){
char ch1[MAX];
Queue Q;
for(int i=0;i<G->n;++i)
visited[i] = FALSE;
InitQueue(&Q);
printf("请输入起始城市名:");
scanf("%s",ch1);
for(int i=0;i<G->n;++i){
if(strcmp(ch1,G->vexs[i])==0){
visited[i]=TRUE;
printf("%s",G->vexs[i]);
EnQueue(&Q,i);
for(int j=0;j<G->n;++j)
if(!visited[j]){
visited[j]=TRUE;
printf("%s",G->vexs[j]);
EnQueue(&Q,j);
while(!QueueEmpty(&Q)){
DeQueue(&Q,&j);
for (int k=0;k<G->n;++k){
if (!visited[k]&&G->edges[j][k]!=INFINITY){
visited[k]=TRUE;
printf("%s",G->vexs[k]);
EnQueue(&Q,k);
}
}
}
}
}
}
}
int LocateVex(MGraph *G,char C[MAX])
{//寻找顶点的位置下标
int i;
for(i=0;i<G->n;i++)
{
if(strcmp(G->vexs[i],C)==0 )
return i;
}
return -1; //没有找到该顶点返回-1
}
void MiniTree_Prim(MGraph *G){//最小生成树Prim算法
int i,j,k,t,min,parent[MAX]={0},lowcost[MAX];
for(i=1;i<G->n;i++){//初始化
lowcost[i]=G->edges[0][i];
}
for(i=1;i<G->n;i++){
int min=INFINITY;
for(j=1;j<G->n;j++){//找最小的边
if(lowcost[j]<min&&lowcost[j]!=0){
min=lowcost[j];
t=j;
}
}
printf("(%s---->%s) 权值为:%d\n",G->vexs[parent[t]],G->vexs[t],min);
lowcost[t]=0;
for(k=1;k<G->n;k++){//更新顶点下标和边
if(lowcost[k]!=0&&G->edges[t][k]<lowcost[k]){
lowcost[k]=G->edges[t][k];
parent[k]=t;
}
}
}
}
void Floyd(MGraph *G){//Floyd算法求两个城市间的最短路径
printf("请输入两个城市名(第一个为起始城市,第二个为结束城市):");
char ch1[MAX],ch2[MAX];
scanf("%s",ch1);
scanf("%s",ch2);
int dist[MAX][MAX],path[MAX][MAX];
for(int i=0;i<G->n;i++){
for(int j=0;j<G->n;j++){
dist[i][j]=G->edges[i][j];
path[i][j] = j;
}
}
for(int k=0;k<G->e;k++){
for(int i=0;i<G->e;i++){
for(int j=0;j<G->e;j++){
if(dist[i][k]!=INFINITY&&dist[k][j]!=INFINITY&&dist[i][k]+dist[k][j]<dist[i][j]){
dist[i][j]=dist[i][k]+dist[k][j];
path[i][j] = path[i][k];
}
}
}
}
printf("Floyd算法求解如下:\n");
for(int i=0;i<G->n;i++){
for(int j=0;j<G->n;j++){
if(strcmp(ch1,G->vexs[i])==0&&strcmp(ch2,G->vexs[j])==0){
printf("%s->%s:最短距离为%-4d:",G->vexs[i],G->vexs[j],dist[i][j]);
int t=path[i][j];
printf("路径为:%s",G->vexs[i]);
while(t!=j){
printf("->%s",G->vexs[t]);
t=path[t][j];
}
printf("->%s\n",G->vexs[j]);
}
}
}
}
void Dijkstra(MGraph *G,int v){//Dijkstra算法求第一个城市至各个城市的最短路径
int dist[MAX],path[MAX],s[MAX];//dist数组用于求出最短路径,s数组用于记录已经确定的最短路径,path数组用于存储路径数组
int min,i,j,u,pre;
for(i=0;i<G->n;i++){
dist[i]=G->edges[v][i];
s[i]=0;
if(G->edges[v][i]<INFINITY)
path[i]=v;
else
path[i]=-1;
}
s[v]=1;path[v]=0;
for(i=0;i<G->n;i++){
min=INFINITY;
u=-1;
for(j=0;j<G->n;j++){
if(s[j]==0&&dist[j]<min){
u=j;
min=dist[j];
}
}
if(u!=-1){
s[u]=1;
for(j=0;j<G->n;j++){
if(s[j]==0)
if(G->edges[u][j]<INFINITY&&dist[u]+G->edges[u][j]<dist[j]){
dist[j]=dist[u]+G->edges[u][j];
path[j]=u;
}
}
}
}
printf("Dijkstra算法求解如下:");
for(i=0;i<G->n;i++){
if(i!=v){
printf("\n%s->%s:",G->vexs[v],G->vexs[i]);
if(s[i]==1){
printf("路径距离为%-4d:",dist[i]);
pre=i;
printf("路径逆序为:");
while(pre!=v){
printf("%s->",G->vexs[pre]);
pre=path[pre];
}
printf("%s",G->vexs[pre]);
}
else
printf("不存在路径\n");
}
}
}
相信能看懂算法的不需要菜单部分,如果实在写不出就私信我吧!