【补充】邻接矩阵、邻接表和关联矩阵的相互转换丨代码详解

邻接矩阵的存储表示

typedef struct MGraph_adjM
{
    char data[MAX_VERTEX_NUM];
    int arc[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
    int vexnum;
    int arcnum;
}MGraph_adjM;

data:顶点的值

arc[][]:邻接矩阵

vecnum:顶点个数

arcnum:弧的个数 

邻接表的存储表示 

typedef struct ArcNode
{
    int adjvex;
    struct ArcNode* nextarc;
}ArcNode;

typedef struct VNode
{
    char data;
    ArcNode* firstArc;
}VNode;

typedef struct MGraph_adjL
{
    VNode adjList[MAX_VERTEX_NUM];
    int vexnum;
    int arcnum;
}MGraph_adjL;

MGraph_adjL是邻接表的结构体定义。

adjList:一个数据类型为VNode的数组,数组的每个元素是一个链表的表头结点。

VNode是链表第一个结点的结构体定义,存储顶点信息和顶点指向的第一条弧。

ArcNode是弧的定义,存储该弧指向的顶点的下标和指向的下一条弧,

 关联矩阵的存储表示

typedef struct MGraph_relaM
{
    int RelaM[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
    int row, col;
}MGraph_relaM;

主函数 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 100

MGraph_adjM createMGraph(char* filename);//读取邻接矩阵文件创建以邻接矩阵表示的图
MGraph_adjL adjMtoList(MGraph_adjM g);//将邻接矩阵转换为邻接表
void printList(MGraph_adjL l);//打印邻接表信息
MGraph_relaM adjMtoRelaM(MGraph_adjL l);//将邻接表转换为关联矩阵
void printMatrix(MGraph_relaM m);//打印关联矩阵
MGraph_adjM RelaMtoAdjM(MGraph_relaM m);//将关联矩阵转换回邻接矩阵(也可以说是已知关联矩阵创建以邻接矩阵表示的图)
void printAdjM(MGraph_adjM g2);//打印邻接矩阵

int main()
{
    // 1、读入邻接矩阵文件
    char filename[] = "D:\\Cfiles\\graph.txt";
    MGraph_adjM g = createMGraph(filename);

    // 2、将邻接矩阵转换为邻接表并打印
    MGraph_adjL l = adjMtoList(g);
    printf("图的邻接表形式表现为:\n");
    printList(l);
    printf("\n");

    // 3、将邻接矩阵转换为关联矩阵并打印
    MGraph_relaM m = adjMtoRelaM(l);;
    printf("关联矩阵为:\n");
    printMatrix(m);
    printf("\n");

    // 4、将关联矩阵转换回邻接矩阵并打印
    MGraph_adjM g2 = RelaMtoAdjM(m);
    printf("转换回邻接矩阵为:\n");
    printAdjM(g2);

    return 0;
}

自定义函数功能详解

1、创建邻接矩阵函数

 读取文本文件"D:\Cfiles\graph.txt",文件具体内容如下:

5
0 1 0 1 0
0 0 0 0 1
0 1 0 1 1
0 0 0 0 0 
0 0 0 0 0
MGraph_adjM createMGraph(char* filename)
{
    MGraph_adjM g;
    FILE* fp = fopen(filename, "r");
    if (fp == NULL)
    {
        printf("打开文件错误");
        return g;
    }
    fscanf(fp, "%d\n", &g.vexnum);
    for (int i = 0; i < g.vexnum; i++)
    {
        g.data[i] = 'A' + i;
        for (int j = 0; j < g.vexnum; j++)
        {
            fscanf(fp, "%d ", &g.arc[i][j]);
            if (g.arc[i][j] == 1)
            {
                g.arcnum++;
            }
        }
        fscanf(fp, "\n");
    }
    fclose(fp);
    return g;
}

2、邻接矩阵转换为邻接表

MGraph_adjL adjMtoList(MGraph_adjM g)
{
    MGraph_adjL l;
    l.vexnum = g.vexnum;
    l.arcnum = g.arcnum;
    for (int k = 0; k < g.vexnum; k++)
    {
        l.adjList[k].data = g.data[k];
        l.adjList[k].firstArc = NULL;
    }
    for (int i = 0; i < l.vexnum; i++)
    {
        for (int j = 0; j < l.vexnum; j++)
        {
            if (g.arc[i][j] == 1)
            {
                ArcNode* arc = (ArcNode*)malloc(sizeof(ArcNode));
                arc->adjvex = j;
                arc->nextarc = NULL;

                if (l.adjList[i].firstArc == NULL)
                {
                    l.adjList[i].firstArc = arc;
                }
                else
                {
                    ArcNode* current = l.adjList[i].firstArc;
                    while (current->nextarc != NULL)
                    {
                        current = current->nextarc;
                    }
                    current->nextarc = arc;
                }
            }
        }
    }
    return l;
}

3、打印邻接表信息

void printList(MGraph_adjL l)
{
    for (int i = 0; i < l.vexnum; i++)
    {
        printf("%c ", l.adjList[i].data);
        ArcNode* current = l.adjList[i].firstArc;
        while (current != NULL)
        {
            printf("->%c ", l.adjList[current->adjvex].data);
            current = current->nextarc;
        }
        printf("\n");
    }
}

4、邻接表转换为关联矩阵

MGraph_relaM adjMtoRelaM(MGraph_adjL l)
{
    MGraph_relaM m;
    m.row = l.vexnum;
    m.col = l.arcnum;
    for (int i = 0; i < m.row; i++)
    {
        for (int j = 0; j < m.col; j++)
        {
            m.RelaM[i][j] = 0;
        }
    }
    int arc = 0;
    for (int i = 0; i < m.row; i++)
    {
        ArcNode* current = l.adjList[i].firstArc;
        while (current != NULL)
        {
            m.RelaM[i][arc] = 1;
            m.RelaM[current->adjvex][arc++] = -1;
            current = current->nextarc;
        }
    }
    return m;
}

5、打印关联矩阵

void printMatrix(MGraph_relaM m)
{
    for (int i = 0; i < m.row; i++)
    {
        for (int j = 0; j < m.col; j++)
        {
            printf("%2d ", m.RelaM[i][j]);
        }
        printf("\n");
    }
}

6、关联矩阵转换回邻接矩阵

MGraph_adjM RelaMtoAdjM(MGraph_relaM m)
{
    MGraph_adjM g2;
    g2.vexnum = m.row;
    g2.arcnum = m.col;
    for (int i = 0; i < m.col; i++)
    {
        g2.data[i] = 'A' + i;
        for (int j = 0; j < m.col; j++)
        {
            g2.arc[i][j] = 0;
        }
        int row, col = 0;
        for (int k = 0; k < m.row; k++)
        {
            if (m.RelaM[k][i] == 1)
            {
                row = k;
            }
            if (m.RelaM[k][i] == -1)
            {
                col = k;
            }
        }
        g2.arc[row][col] = 1;
    }
    return g2;
}

7、 打印邻接矩阵

void printAdjM(MGraph_adjM g2)
{
    for (int i = 0; i < g2.vexnum; i++)
    {
        for (int j = 0; j < g2.vexnum; j++)
        {
            printf("%d ", g2.arc[i][j]);
        }
        printf("\n");
    }
}

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值