图的简单应用(C/C++实现)

简介: 存档: 1 #include 2 #include 3 #define maxv 10//定义最大顶点数 4 typedef char elem;//图中顶点的数据类型 5 #include "graph.

存档:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #define maxv 10//定义最大顶点数
 4 typedef char elem;//图中顶点的数据类型
 5 #include "graph.h"
 6 void main()
 7 {
 8     elem v0;
 9     int v;
10     mgraph g;
11     printf("1.初始化函数测试:\n");
12     initial(g);
13     printf("2.创建函数测试:\n");
14     create(g);
15     printf("3.输出函数测试:\n");
16     printg(g);
17     printf("4.求最短路径:\n");
18     printf("请输出源顶点数据v0:");
19     scanf("%c",&v0);
20     v=locate(g,v0);
21     dijkstra(g,v);
22     printf("5.输出最短路径:\n");
23     printpath(g,v);
24     printf("\n");
25 }
  1 //有向带权网的邻接矩阵,顶点数据为字符型
  2 #define inf 32767
  3 typedef struct MGraph
  4 {
  5     elem vexes[maxv];//顶点表
  6     int edges[maxv][maxv];//邻接矩阵
  7     int n,e;//顶点数n和边数e
  8 }mgraph;
  9 void initial(mgraph &g)//初始化函数
 10 {
 11     int i,j;
 12     g.e=0;
 13     g.n=0;
 14     for(j=0;j<maxv;j++)//建立顶点表
 15         g.vexes[j]=0;
 16     for(i=0;i<maxv;i++)
 17     {
 18         for(j=0;j<maxv;j++)
 19         {
 20             g.edges[i][j]=inf;//初始化邻接矩阵
 21         }
 22     }
 23 }
 24 int locate(mgraph g,elem u)//查找顶点对应的数组下标值
 25 {
 26     for(int i=0;i<g.n;i++)
 27     {
 28         if(g.vexes[i]==u)
 29             return i;
 30     }
 31     return -1;
 32 }
 33 void create(mgraph &g)//创建有向带权网的邻接矩阵存储
 34 {
 35     int i,j,k,w;
 36     elem u,v;
 37     printf("请输入有向图的顶点数:");
 38     scanf("%d",&g.n);
 39     printf("请输入有向图的弧数:");
 40     scanf("%d",&g.e);
 41     fflush(stdin);//清空缓存中的数据
 42     printf("请输入字符型顶点数据,如ABCD:");
 43     for(j=0;j<g.n;j++)
 44         scanf("%c",&g.vexes[j]);//建立顶点表
 45     fflush(stdin);
 46     printf("请输入弧的信息,格式:弧尾,弧头,权值\n");
 47     for(k=0;k<g.e;k++)
 48     {
 49         scanf("%c,%c,%d",&u,&v,&w);
 50         i=locate(g,u);
 51         j=locate(g,v);
 52         g.edges[i][j]=w;
 53         fflush(stdin);
 54     }
 55 }
 56 void printg(mgraph g)//输出有向带权网的邻接矩阵
 57 {
 58     int i,j;
 59     printf("输入图的邻接矩阵存储信息:\n");
 60     printf("顶点数据:\n");
 61     for(i=0;i<g.n;i++)
 62         printf("%d: %c\n",i,g.vexes[i]);
 63     printf("邻接矩阵数据:\n");
 64     for(i=0;i<g.n;i++)
 65     {
 66         for(j=0;j<g.n;j++)
 67         {
 68             if(g.edges[i][j]==inf)
 69                 printf("");
 70             else
 71                 printf("%3d",g.edges[i][j]);
 72         }
 73         printf("\n");
 74     }
 75 }
 76 int dist[maxv];//dist存当前找到的最短路径长度
 77 int path[maxv];//当前找到的最短路径最后的一个中转顶点
 78 bool s[maxv];//标记当前是否已求出最短路径,false表示没求出,true表示已求出
 79 void dijkstra(mgraph g,int v)//迪杰斯特拉算法从顶点v到其余各顶点的最短路径
 80 {
 81     int mindis,i,j,u;
 82     for(i=0;i<g.n;i++)
 83     {
 84         dist[i]=g.edges[v][i];//当前最短路径长度初始化
 85         s[i]=false;//s[]标记还没求出当前路径
 86         if(g.edges[v][i]<inf)//初始化当前找到的最短路径最后一个中转顶点
 87             path[i]=v;
 88         else
 89             path[i]=-1;
 90     }
 91     s[v]=true;//源点编号v标记已求出最短路径
 92     path[v]=0;//源点v没有前驱顶点
 93     for(i=0;i<g.n;i++)//循环直到所有顶点的最短路径都求出或没有最短路径
 94     {
 95         mindis=inf;
 96         u=-1;//存当前找到的路径最短的新顶点下标
 97         for(j=0;j<g.n;j++)//选取不在s中且具有最小距离的顶点u
 98         {
 99             if((s[j]==false)&&(dist[j]<mindis))
100             {
101                 u=j;
102                 mindis=dist[j];
103             }
104         }
105         if(mindis<inf)//如果找到了新的最短路径
106         {
107             s[u]=true;//新选出顶点u标记为找到了最短路径
108             for(j=0;j<g.n;j++)//修改未找到最短路径顶点信息
109             {
110                 if(s[j]==false)
111                 {
112                     if(g.edges[u][j]<inf&&dist[u]+g.edges[u][j]<dist[j])
113                     {
114                         dist[j]=dist[u]+g.edges[u][j];//修改当前最短路径长度
115                         path[j]=u;//修改当前最短路径最后一个中转点
116                     }
117                 }
118             }
119         }
120     }
121 }
122 void printpath(mgraph g,int v)//输出最短路径和最短路径长度
123 {
124     int i,j,w;
125     int road[maxv];//为输出最短路径做临时存储
126     printf("%c到其他各顶点有没有找到最短路径:\n",g.vexes[v]);
127     for(i=0;i<g.n;i++)
128     {
129         if(s[i])
130             printf("%d:有  ",i);
131         else
132             printf("%d:无  ",i);
133     }
134     printf("\n");
135     for(i=0;i<maxv;i++)
136         road[i]=-1;
137     for(i=0;i<g.n;i++)
138     {
139         if((s[i]==true)&&(i!=v))//当前顶点有最短路径,并且不是源点
140         {
141             printf("从%c到%c的最短路径长度为:%d\t路径为:",g.vexes[v],g.vexes[i],dist[i]);
142             printf("%c->",g.vexes[v]);
143             w=path[i];//最短路径途径的顶点
144             j=0;//为实现逆转标记途径顶点数
145             while(w!=v)//回溯途径顶点
146             {
147                 road[j]=w;
148                 j++;
149                 w=path[w];
150             }
151             for(j--;j>=0;j--)//输出最短路径
152             {
153                 printf("%c->",g.vexes[road[j]]);
154                 road[j]=-1;
155             }
156             printf("%c\n",g.vexes[i]);
157         }
158         else
159             printf("从%c到%c不存在路径\n",g.vexes[v],g.vexes[i]);
160     }
161 }

运行结果如下:

 

目录
相关文章
|
8天前
|
存储 C++ 容器
C++STL(标准模板库)处理学习应用案例
使用C++ STL,通过`std:vector`存储整数数组 `{5, 3, 1, 4, 2}`,然后利用`std::sort`进行排序,输出排序后序列:`std:vector&lt;int&gt; numbers; numbers = {5, 3, 1, 4, 2}; std:sort(numbers.begin(), numbers.end()); for (int number : numbers) { std::cout &lt;&lt; number &lt;&lt; &quot; &quot;; }`
15 2
|
20天前
|
安全 算法 C++
【C/C++ 泛型编程 应用篇】C++ 如何通过Type traits处理弱枚举和强枚举
【C/C++ 泛型编程 应用篇】C++ 如何通过Type traits处理弱枚举和强枚举
44 3
|
20天前
|
设计模式 安全 算法
【C/C++ 类型转换 】深入理解C++向上转型:从基础到应用
【C/C++ 类型转换 】深入理解C++向上转型:从基础到应用
41 0
|
21天前
|
算法 编译器 C语言
【C++ 异常】C++ 标准库异常类及其应用
【C++ 异常】C++ 标准库异常类及其应用
16 0
|
存储 安全 算法
【C++智能指针 相关应用】深入探索C++智能指针:跨进程、动态库与最佳实践
【C++智能指针 相关应用】深入探索C++智能指针:跨进程、动态库与最佳实践
58 5
|
8天前
|
程序员 C++
C++语言模板学习应用案例
C++模板实现通用代码,以适应多种数据类型。示例展示了一个计算两数之和的模板函数`add&lt;T&gt;`,可处理整数和浮点数。在`main`函数中,展示了对`add`模板的调用,分别计算整数和浮点数的和,输出结果。
9 2
|
19天前
|
设计模式 算法 中间件
【C++ 可调用对象的应用】C++设计模式与现代编程技巧:深入可调用对象的世界
【C++ 可调用对象的应用】C++设计模式与现代编程技巧:深入可调用对象的世界
108 1
|
20天前
|
存储 设计模式 算法
【C/C++ 数据结构 线性表】深入理解与实现栈:从基础到应用的全面探索
【C/C++ 数据结构 线性表】深入理解与实现栈:从基础到应用的全面探索
52 0
|
21天前
|
Unix Linux C++
【C/C++ 造轮子】Linux异步计时器:深入探讨和应用 (Linux Asynchronous Timers: An In-depth Exploration and Application)
【C/C++ 造轮子】Linux异步计时器:深入探讨和应用 (Linux Asynchronous Timers: An In-depth Exploration and Application)
52 1
|
21天前
|
设计模式 存储 算法
【C++ 函数调用操作符】探究C++中的函数调用操作符 基础到高级应用
【C++ 函数调用操作符】探究C++中的函数调用操作符 基础到高级应用
271 0