引入

上节,我们介绍了如何根据需要创建有向图、无向图、并且将其结构存储起来,今天我们就将图输出,并且输出一个邻接矩阵,看看我们输入的图对不对。

输出图结构

我们还是分段讲解

输出图的基本信息

//前三个比较简单,就是数据结构体中存储的数据
void print_MG(Graph MG){
if(MG.type == DG)
    {
        printf("图类型 : 有向图:\n");
    }
    else
    {
        printf("图类型:无向图:\n");
    }
    printf("图中的顶点有: %d 个\n",MG.vsnum);
    printf("图中的边/弧有: %d 个\n",MG.esnum);
//输出顶点得集合这里,我们需要用顶点数作为循环结束条件
 printf("顶点的集合:");
    for (i = 1; i <= MG.vsnum; i++){
        printf("%c ", MG.vs[i]);
    }
    }

我们输出了图的一些基本信息

  • 输出函数首先接收到图结构体指针
  • 图的类型,直接从结构体调用
  • 顶点数量、边得数量,也都直接从结构体调用
  • 在输出顶点集合的时候,我们需要根据顶点的数量循环输出

输出邻接矩阵

//有多少顶点循环多少次
 for (i = 1; i <= MG.vsnum; i++)
    {
        printf("%c ", MG.vs[i]);  //每一行第一列输出顶点
        j = 1;
        for (; j <= MG.vsnum; j++){
            printf("%d ", MG.es[i][j]);
        }
        printf("\n");
    }

其实就是格式化输出二维数组的全部元素

  • 一开始先输出这一行表示的顶点名称
  • 然后通过内层 for 循环不断的输出这一行的数据
  • 输出完这一行,\n 换行继续输出

总代码

内容和上一讲相同,我们可以试着自己再写一遍,很简单~

#include <stdio.h>
#include <stdlib.h>
#define MAX 50

typedef enum{DG,UDG} GraphType;

typedef struct {
    char vex[MAX];  //定义一维数组存储顶点
    int arcs[MAX][MAX];  //定义二维数组存储边
    int vexnum,arcnum;  //存储顶点和边的数量
    GraphType type;  //存储图的类型
}Graph;

int position(char c , Graph *G){
    int i;
    for(i=1;i<=G->vexnum;i++){
        if(G->vex[i]==c){
            return i;
        }
    }
    return 0;
}

void Create(Graph * G){
    //获取图的类型
    int type;
    printf("请输入图的类型,有向图输入1,无向图输入0:");
    scanf("%d",&type);
    if(type==1){
        G->type=DG;
    }else if(type==0){
        G->type=UDG;
    }else{
        printf("输入的类型不正确!\n");
        return;
    }
    //获取图得顶点数和边数
    printf("图有几个顶点:");
    scanf("%d",&G->vexnum);
    printf("图有几条边:");
    scanf("%d",&G->arcnum);
    getchar();
    //获得每个顶点得值
    
    for(int k=1;k<=G->vexnum;k++){
        printf("请输入第%d个结点的值:",k);
        scanf("%s",&G->vex[k]);
        getchar();
    }
    //值全部获得完毕
    
    //矩阵初始化
    int i,j;
    for (i = 1; i <= G->vexnum; i++)
    {
        for (j = 1; j <= G->vexnum; j++)
        {
            G->arcs[i][j] = 0;
        }
    }
    //有多少个结点循环多少次
    char V1,V2;
    int V1p,V2p;
    for(int l=1;l<=G->arcnum;l++){
        printf("请输第%d个边的信息:",l);
        scanf("%c %c",&V1,&V2);
        V1p=position(V1,G);
        V2p=position(V2,G);
        
        if(G->type==UDG){
            G->arcs[V1p][V2p]=G->arcs[V2p][V1p]=1;
        }else{
            G->arcs[V1p][V2p]=1;
        }
        getchar();
    }
}

void print_MG(Graph MG){
    printf("-------------------------------\n");
    int i, j;
    if(MG.type == DG)
    {
        printf("图类型 : 有向图\n");
    }
    else
    {
        printf("图类型:无向图\n");
    }
    printf("图中的顶点有: %d 个\n",MG.vexnum);
    printf("图中的边/弧有: %d 个\n",MG.arcnum);
    
    printf("顶点的集合:");
    for (i = 1; i <= MG.vexnum; i++){
        printf("%c ", MG.vex[i]);
    }
    printf("\n");
    printf("邻接矩阵:\n");
    
    for (i = 1; i <= MG.vexnum; i++){
        printf("%c ", MG.vex[i]);
        j = 1;
        for (; j<=MG.vexnum; j++){
            printf("%d ", MG.arcs[i][j]);
        }
        printf("\n");
    }
}

int main(){
    Graph MG;
    Create(&MG);
    print_MG(MG);
    return 0;
}

V0 V1 v2 v3
V0 0 1 1 1
V1 1 0 1 0
V2 1 1 0 1
V3 1 0 1 0

我们将上面的图输入程序,我们用 a、b、c、d 代替v1、v2、v3、v4

运行结果
请输入图的类型,有向图输入1,无向图输入0:0
图有几个顶点:4
图有几条边:5
请输入第1个结点的值:a
请输入第2个结点的值:b
请输入第3个结点的值:c
请输入第4个结点的值:d
请输第1个边的信息:a b
请输第2个边的信息:b c
请输第3个边的信息:c d
请输第4个边的信息:d a

请输第5个边的信息:a c

图类型:无向图
图中的顶点有: 4 个
图中的边/弧有: 5 个
顶点的集合:a b c d
邻接矩阵:
a 0 1 1 1
b 1 0 1 0
c 1 1 0 1
d 1 0 1 0

运行结果同矩阵相同,成功!