图的基本操作(C语言)


编译器: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;
}

测试结果如下:
在这里插入图片描述

  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值