图的操作与实现——简易城市交通网

本次题目为数据结构课设:

(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");
        }
    }
}


相信能看懂算法的不需要菜单部分,如果实在写不出就私信我吧!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Disaster_Star

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值