图的基本操作
编译器:VS Code
语言:C语言
图(顺序存储)
无向图、有向图、无向网、有向网
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define maxvertnum 100 //最大的顶点个数
typedef enum{DG,UDG,DN,UDN} graghkind; //图的类型(保存的是常量)
typedef struct{
int adj; //对于无权图,用1表示相邻,0表示不相邻;对于权重图,直接为权重值
int info; //边的描述信息(弧、边、额外信息指针)
}Edge,adjmatrix[maxvertnum][maxvertnum]; //后者为二维数组(邻接矩阵)
typedef struct {
char vert[maxvertnum]; //图得所有顶点得名称(int、char类型)
adjmatrix edges; //邻接矩阵adjmatrix命名为edges(记录顶点之间的关系)
int vertnum,edgenum; //图的顶点数和(弧/边)数
graghkind kind; //图的类型
}amgragh;
//根据点的名称查找下标
int locatevex(amgragh g,char v)
{
int k=0;
//遍历一位数组,找到变量v
for(;k<g.vertnum;k++){
if(g.vert[k]==v){ //如果下标存在就跳出循环
break;
}
}
//如果找不到。输入提示语句
if(k>g.vertnum){
printf("没有这样的值\n");
return false;
}
return k;
}
//创建无向图
int create_UG(amgragh &g)
{
/*
边数=顶点数*(顶点数)/2
邻接矩阵关于对角线堆成
*/
printf("=====无向图=====\n");
printf("请输入无向图的顶点数和边数:");
scanf("%d %d",&g.vertnum,&g.edgenum);
if(g.edgenum>g.vertnum*(g.vertnum-1)/2){ //边数=顶点数*(顶点数)/2
int edgenum;
printf("边数<=%d\n",g.vertnum*(g.vertnum-1)/2);
printf("输入错误\n");
return false;
}
//输入无向图的顶点的名称
printf("请输入顶点的名称(空号隔开):");
for(int i=0;i<g.vertnum;i++){
scanf("%s",&g.vert[i]); //输入每个顶点的名称
}
//strcpy(&g.vert[0],"男18");
//strcpy(&g.vert[1],"男17");
//strcpy(&g.vert[2],"男16");
//strcpy(&g.vert[3],"男15");
//strcpy(&g.vert[4],"男14");
//strcpy(&g.vert[5],"男13");
//strcpy(&g.vert[6],"男12");
//初始化邻接矩阵,即0矩阵
for(int i=0;i<g.vertnum;i++){
for(int j=0;j<g.vertnum;j++){
g.edges[i][j].adj=0; //初始化邻接矩阵
g.edges[i][j].info=NULL; //无向图没有权重值
}
}
//图转为邻接矩阵存储
char v1[40],v2[40];
int i=0,j=0;
for(int k=0;k<g.edgenum;k++){
printf("请输入弧头、弧尾:");
scanf("%s %s",v1,v2); //输入下一个点的名称
i=locatevex(g,*v1); //根据顶点名称找到其在邻接矩阵中的下标
j=locatevex(g,*v2); //第二个元素
printf("下标=%d %d\n",i,j);
g.edges[i][j].adj=1; //无向图的二维矩阵沿对角线堆成
g.edges[j][i].adj=1;
}
printf("无向图创建成功!!!\n");
//输出无向图的邻接矩阵
printf("====无向图的邻接矩阵====\n");
for(int i=0;i<g.vertnum;i++){
for(int j=0;j<g.vertnum;j++){
printf("%3d",g.edges[i][j].adj);
}
printf("\n");
}
return true;
}
//创建有向图
int create_DG(amgragh &dg)
{
/*
边数=顶点数*(顶点数)
弧头:head
弧尾:tail
顶点之间的关:tail->head
*/
printf("=====有向图=====\n");
printf("请输入有向图的顶点数和弧数:");
scanf("%d %d",&dg.vertnum,&dg.edgenum); //输入顶点数个边数
//依次输入顶点的名称
printf("请输入顶点的名称(空号隔开):");
for(int i=0;i<dg.vertnum;i++){
scanf("%s",&dg.vert[i]); //输入每个顶点的名称
}
if(dg.edgenum>dg.vertnum*(dg.vertnum-1)){ //边数=顶点数*(顶点数)
int edgenum;
printf("边数<=%d\n",dg.vertnum*(dg.vertnum-1));
printf("输入错误\n");
return false;
}
//初始化邻接矩阵,即0矩阵
for(int i=0;i<dg.vertnum;i++){
for(int j=0;j<dg.vertnum;j++){
dg.edges[i][j].adj=0; //初始化邻接矩阵
dg.edges[i][j].info=NULL; //无向图没有权重值
}
}
//有向图转为邻接矩阵存储
char head[40],tail[40];
int i=0,j=0;
for(int k=0;k<dg.edgenum;k++){
printf("请输入边邻接顶点的名称(空号隔开):");
scanf("%s %s",head,tail); //输入下一个点的名称
if(strlen(head)!=strlen(tail)){
printf("输入错误!!!");
return false;
}
i=locatevex(dg,*head); //弧头为i
j=locatevex(dg,*tail); //弧尾为j
printf("下标=%d %d\n",i,j);
dg.edges[i][j].adj=1; //有向图的二维矩阵
}
printf("无向图创建成功!!!\n");
//输出有向图的邻接矩阵
printf("====无向图的邻接矩阵====\n");
for(int i=0;i<dg.vertnum;i++){
for(int j=0;j<dg.vertnum;j++){
printf("%3d",dg.edges[i][j].adj);
}
printf("\n");
}
return true;
}
//创建无向网
/*和无向图的唯一区别就是,邻接矩阵存储的是权重值*/
int create_UDN(amgragh &g)
{
printf("=====无向网=====\n");
printf("请输入无向网的顶点数和边数:");
scanf("%d %d",&g.vertnum,&g.edgenum);
if(g.edgenum>g.vertnum*(g.vertnum-1)/2){ //边数=顶点数*(顶点数)/2
int edgenum;
printf("边数<=%d\n",g.vertnum*(g.vertnum-1)/2);
printf("输入错误\n");
return false;
}
//初始化邻接矩阵
for(int i=0;i<g.vertnum;i++){
for(int j=0;j<g.vertnum;j++){
g.edges[i][j].adj=0; //初始化邻接矩阵
g.edges[i][j].info=1000; //无向网边的信息
}
}
//输入无向网的顶点的名称
printf("请输入顶点的名称(空号隔开):");
for(int i=0;i<g.vertnum;i++){
scanf("%s",&g.vert[i]); //输入每个顶点的名称
}
//将无向网转化为邻接矩阵存储
char v1[40],v2[40];
int w;
for(int k=0;k<g.edgenum;k++){
printf("请输入边邻接顶点的名称、弧长的信息(空号隔开):");
scanf("%s %s %d",v1,v2,&w); //输入下一个点的名称
int i=locatevex(g,*v1); //根据顶点名称找到其在邻接矩阵中的下标
int j=locatevex(g,*v2); //第二个元素
printf("下标=%d %d\n",i,j);
g.edges[i][j].info=w; //无向图的二维矩阵沿对角线对称
g.edges[j][i].info=w;
}
//输出无向网的邻接矩阵
for(int i=0;i<g.edgenum;i++){
for(int j=0;j<g.edgenum;j++){
printf("%6d",g.edges[i][j].info); //输出的是弧的信息
}
printf("\n");
}
}
//创建有向网
/*和有向图的唯一区别就是:邻接矩阵是权重值*/
int create_DN(amgragh &dg)
{
printf("=====有向网=====\n");
printf("请输入有向网的顶点数和弧数:");
scanf("%d %d",&dg.vertnum,&dg.edgenum); //输入顶点数个边数
if(dg.edgenum>dg.vertnum*(dg.vertnum-1)){ //边数=顶点数*(顶点数)
int edgenum;
printf("边数<=%d\n",dg.vertnum*(dg.vertnum-1));
printf("输入错误\n");
return false;
}
//依次输入顶点的名称
printf("请依次输入顶点的名称:");
for(int i=0;i<dg.vertnum;i++){
scanf("%s",&dg.vert[i]); //输入每个顶点的名称
}
//初始化邻接矩阵,即0矩阵
for(int i=0;i<dg.vertnum;i++){
for(int j=0;j<dg.vertnum;j++){
dg.edges[i][j].adj=0; //初始化邻接矩阵
dg.edges[i][j].info=1000; //无向图没有权重值
}
}
//有向图转为邻接矩阵存储
char head[40],tail[40];
int w;
for(int k=0;k<dg.edgenum;k++){
printf("请输入弧头、弧尾、弧的信息(空号隔开):");
scanf("%s %s %d",head,tail,&w); //输入下一个点的名称
if(strlen(head)!=strlen(tail)){
printf("输入错误!!!");
return false;
}
int i=locatevex(dg,*head); //弧头为i
int j=locatevex(dg,*tail); //弧尾为j
printf("下标=%d %d\n",i,j);
dg.edges[i][j].info=w; //有向图的二维矩阵
}
printf("有向网创建成功!!!\n");
//输出有向图的邻接矩阵
printf("====有向网的邻接矩阵====\n");
for(int i=0;i<dg.vertnum;i++){
for(int j=0;j<dg.vertnum;j++){
printf("%6d",dg.edges[i][j].info);
}
printf("\n");
}
return true;
}
//选择创建的图
int creategragh(amgragh &g)
{
int expression;
printf("0.退出\n1.UDG\n2.DG\n3.UDN\n4.DN\n");
printf("请选择:");
scanf("%d",&expression);
switch (expression)
{
case 1:{
create_UG(g); //创建无向图
break;
}
case 2:{
create_DG(g); //创建有向图
break;
}
case 3:{
create_UDN(g); //创建无向网
break;
}
case 4:{
create_DN(g); //创建有向网
break;
}
default:
break;
}
return true;
}
int main()
{
amgragh G;
creategragh(G);
return true;
}
测试结果如下: