/**
*    实验题目:
*        实现图的邻接矩阵和邻接表存储
*    实验目的:
*        领会图的两种主要存储结构和图基本运算算法设计
*    实验内容:
*        编写程序,设计带权图的邻接矩阵与邻接表的创建和输出运算,
*    并在此基础上设计一个主程序,完成如下功能:
*    1、建立如图8-1所示的有向图G的邻接矩阵,并输出之。
*    2、建立如图8-1所示的有向图G的邻接表,并输出之。
*    3、销毁图G的邻接表。
*/

图8-1 带权有向图

#include <stdio.h>
#include <malloc.h>

#define INF     32767               //定义∞
#define MAXV    100                 //最大顶点个数

typedef char InfoType;
/*-------------------------以下定义邻接矩阵类型---------------------------*/
typedef struct
{
    int no;                         //顶点编号
    InfoType info;                  //顶点信息
}VertexType;                        //顶点类型

typedef struct
{
    int edges[MAXV][MAXV];          //邻接矩阵数组(用一个二维数组存放顶点间关系(边或弧)的数据)
    int n;                          //顶点数
    int e;                          //边数
    VertexType vexs[MAXV];          //存放顶点信息(用一个一维数组存放图中所有顶点数据)
}MatGraph;                          //完整的图邻接矩阵类型

//邻接表表示法-将每个顶点的邻接点串成一个单链表
/*-----------以下定义邻接表类型--------------*/
typedef struct ArcNode
{
    int adjvex;                     //该边的邻接点编号
    struct ArcNode *nextarc;        //指向下一条边的指针
    int weight;                     //该边的相关信息,如权值(用整型表示)
}ArcNode;                           //边结点类型

typedef struct VNode
{
    InfoType info;                  //顶点其他信息
    int cnt;                        //存放顶点入度,仅用于拓扑排序
    ArcNode *firstarc;              //指向第一条边
}VNode;                             //邻接表结点类型

typedef struct
{
    VNode adjlist[MAXV];            //邻接表头结点数组
    int n;                          //图中顶点数
    int e;                          //图中边数
}AdjGraph;                          //完整的图邻接表类型

/*-------------------------邻接矩阵的基本运算算法---------------------------*/
/*------------由边数组A、顶点数n和边数e创建图的邻接矩阵g--------------------*/
void CreateMat(MatGraph &g, int A[MAXV][MAXV], int n, int e)
{
    int i, j;

g.n = n;
    g.e = e;
    for(i = 0; i < g.n; i++)
        for(j = 0; j < g.n; j++)
            g.edges[i][j] = A[i][j];
}

/*------------输出邻接矩阵g--------------------*/
void DispMat(MatGraph g)
{
    int i, j;

for(i = 0; i < g.n; i++)
    {
        for(j = 0; j < g.n; j++)
        {
            if(g.edges[i][j] != INF)
                printf("%4d", g.edges[i][j]);
            else
                printf("%4s", "∞");
        }
        printf("\n");
    }
}

/*-------------------------邻接表的基本运算算法---------------------------*/
/*-------------------由边数组A、顶点数n和边数e创建图的邻接表G--------------------*/
void CreateAdj(AdjGraph *&G, int A[MAXV][MAXV], int n, int e)
{
    int i, j;
    ArcNode *p;

G = (AdjGraph *)malloc(sizeof(AdjGraph));
    for(i = 0; i < n; i++)                              //给邻接表中所有头结点的指针域置初值NULL
    {
        G->adjlist[i].firstarc = NULL;
    }

for(i = 0; i < n; i++)                              //检查邻接矩阵中的每个元素
    {
        for(j = n - 1; j >= 0; j--)
        {
            if(A[i][j] != 0 && A[i][j] != INF)          //存在一条边
            {
                p = (ArcNode *)malloc(sizeof(ArcNode)); //创建一个结点p
                p->adjvex = j;                          //邻接点编号
                p->weight = A[i][j];                    //边的权重
                p->nextarc = G->adjlist[i].firstarc;    //采用头插法插入结点p
                G->adjlist[i].firstarc = p;
            }
        }
    }
    G->n = n;
    G->e = e;
}

/*-------------------输出邻接表G--------------------*/
void DispAdj(AdjGraph *G)
{
    ArcNode *p;

for(int i = 0; i < G->n; i++)
    {
        p = G->adjlist[i].firstarc;
        printf("顶点%d: ", i);
        while(p != NULL)
        {
            printf("%3d[%d]->", p->adjvex, p->weight);  //邻接点编号[权重]
            p = p->nextarc;
        }
        printf("∧\n");
    }
}

/*-------------------销毁图的邻接表G--------------------*/
void DestroyAdj(AdjGraph *&G)
{
    ArcNode *pre, *p;

for(int i = 0; i < G->n; i++)
    {
        pre = G->adjlist[i].firstarc;                   //pre指向第i个单链表的首结点
        if(pre != NULL)
        {
            p = pre->nextarc;
            while(p != NULL)                            //释放第i个单链表的所有边结点
            {
                free(pre);
                pre = p;
                p = p->nextarc;
            }
            free(pre);
        }
    }
    free(G);                                            //释放头结点数组
}

int main(void)
{
    MatGraph g;
    AdjGraph *G;
    int n = 6;                                  //图中的顶点数
    int e = 10;                                 //图中的边数
    int A[MAXV][MAXV] = {
        {0, 5, INF, 7, INF, INF}, {INF, 0, 4, INF, INF, INF},
        {8, INF, 0, INF, INF, 9}, {INF, INF, 5, 0, INF, 6},
        {INF, INF, INF, 5, 0, INF}, {3, INF, INF, INF, 1, 0}
    };

CreateMat(g, A, n, e);
    printf("(1)图的邻接矩阵:\n");
    DispMat(g);

CreateAdj(G, A, n, e);
    printf("(2)图的邻接表:\n");
    DispAdj(G);
    printf("(3)销毁图的邻接表\n");
    DestroyAdj(G);

return 0;
}
测试结果:

(1)图的邻接矩阵:
   0   5  ∞   7  ∞  ∞
  ∞   0   4  ∞  ∞  ∞
   8  ∞   0  ∞  ∞   9
  ∞  ∞   5   0  ∞   6
  ∞  ∞  ∞   5   0  ∞
   3  ∞  ∞  ∞   1   0
(2)图的邻接表:
顶点0:   1[5]->  3[7]->∧
顶点1:   2[4]->∧
顶点2:   0[8]->  5[9]->∧
顶点3:   2[5]->  5[6]->∧
顶点4:   3[5]->∧
顶点5:   0[3]->  4[1]->∧
(3)销毁图的邻接表

实现图的邻接矩阵和邻接表存储相关推荐

  1. 实现图的邻接矩阵和邻接表的存储

    十五,实现图的邻接矩阵和邻接表的存储 #include<stdio.h> #include<stdlib.h> #define max 100 #define INF 3276 ...

  2. 将图的广度优先遍历在邻接矩阵和邻接表存储结构上分别实现_图解:什么是“图”?

    从今天开始,我们开始介绍图的相关算法 什么是"图" 1.背景 作为图的开始,我们先来看一个经典的问题,它被认为是图论的起源. 这个问题是基于一个现实生活中的事例:河中心有两个小岛. ...

  3. 有向无环图(邻接矩阵和邻接表)

    一.图的定义 图是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为: G=(V,E) 其中:G表示一个图,V是图G中顶点的集合,E是图G中顶点之间边的集合. 注: 在线性表中,元素个数可以为零, ...

  4. 一个图的带权邻接表存储结构的应用

    情景:在一个图中,已知经过的一串n节点信息,希望显示经过的路径. 数据组织: 点要素:存放图中的点信息,必含Id字段 线要素:存放编辑好的路径信息,必含"Start"和" ...

  5. c语言邻接表的构建_c语言数据结构--图的邻接矩阵和邻接表操作的基本操作

    #include #include #include #define MAX 100 typedef char DataType; typedef int VectorRelationType; ty ...

  6. 【创建图的邻接矩阵和邻接表】

    目录 1.创建图的邻接矩阵 1.1源码 1.2运行效果 2. 创建图的邻接表 2.1源码

  7. 图的邻接矩阵和邻接表

    图的邻接矩阵存储方式是两个数组来表示图.一个一维数组存储图中顶点信息,一个二维数组(即为邻接矩阵)存储图中的边或弧的信息 设图G有n个顶点,则邻接矩阵为一个n×n的方阵,定义为: 抽象数据类型如下 t ...

  8. [数据结构]邻接矩阵和邻接表存储的图DFS,BFS算法时间复杂度分析

  9. 有向图的邻接矩阵和邻接表画法

    本例子展示有向图画邻接表和邻接矩阵,反过来也是如此 大三时自学了了数据结构中的图,发现图中有邻接矩阵和邻接表,作为笔记记录下来 如下图所示,给了一个有向图,求邻接矩阵 怎么做呢? 第一步:和无向图类似 ...

最新文章

  1. 用C写有面向对象特点的程序
  2. hexo d 部署博客时出错
  3. nth_element
  4. 前端学习(3121):react-hello-react的总结state
  5. 基于高光谱技术的农作物常见病害监测研究
  6. 零基础学python还是c语言-入门是不是应该选择C而不是直接学Python?
  7. VOSviewer安装及配置
  8. nios程序烧写到epcs方法
  9. android opengl 帧动画,Android OpenGLES2.0(十三)——流畅的播放逐帧动画
  10. 虚拟仿真实训教学管理及资源共享平台虚拟实训开发对接文档
  11. idea 光标 快捷键_idea光标快捷键
  12. 2022-12-24 三阶魔方完整教程和口诀速记,二级魔方教程
  13. CMOS MIPI EOT 学习 基于Zynq高速串行CMOS接口的设计与实现
  14. 使用微信号开通检测软件的成功案例(一)
  15. Linux一键安装xrdp,如何在Linux系统Ubuntu 20.04中安装xrdp实现远程桌面连接RDP
  16. 使用FPGA实现的图像锐化算法(USM)设计
  17. 获取CPU型号和序列号
  18. 钉钉内网穿透工具,如何使用钉钉小程序访问内网
  19. 修改手机服务器密码是不是获取不了通讯录,手机运营商服务密码改了,别人还会读取到通讯录吗...
  20. 怎样将直流电转变为交流电?

热门文章

  1. gis可达性分析步骤_基于三维GIS技术的公路交通数字孪生系统
  2. 伺服控制原理 及RT and IRT
  3. 足球数据API接口 - 【足球赛事分析数据】API调用示例代码
  4. oop练习(第11周)
  5. 学习笔记=《你不知道的JavaScript(上卷)第二部分》第一章:关于this
  6. 一个完整的LED灯具散热优化分析计算方案
  7. C++编程-牛客网-逛街
  8. [Test]测试相关资料
  9. java生成随机邮箱_Java随机生成姓名、邮箱、手机号码
  10. libuv 原理_进程 | libuv中文教程