图--分类及存储结构(数据结构)

本文介绍了图论中的基本概念,包括无向图与有向图的定义、连通性和生成树等,并详细阐述了图的两种主要存储结构——邻接矩阵与邻接表的特点及其适用场景。
  1. 无向图:
    1)度:有几条边和该点相连,该点的度就是几。
    2)连通图:无向图中,若任意两点之间都有路径相连(不一定是直接相连),则该图是连通图(或者该图中能找到一条路径,包含所有的点,那么该图也为连通图)。
    3)连通分量:无向图中的极大连通子图,称为该图的连通分量(所谓极大,就是顶点尽量多)。若图本身连通,则连通分量唯一,是其自身。
    4)生成树:连通图的一个含有全部顶点的子图,如果其连通且极小,那么该图就是一颗最小生成树(若图有n个顶点,则有(n-1)条边)。
    5)树是含边数最少的连通图,一个含n个点的连通图最少含有(n-1)条边;若一个图含有(n-1)条边,那么该图一定是连通图;若含有n个点的图含有少于(n-1)条边,那么该图一定不连通,若含有多余(n-1)条边,那么该图一定有回路。
    6)对于非连通图,由各个连通分量的生成树组成的集合称为此非连通图的生成森林。

  2. 有向图:
    1)度:以该点为弧头的边(弧的箭头指向该点)有几条,该点的入度就是几,以该点为弧尾的边有几条,该点的出度就是几,该点的度为出度和入度的和。
    2)强连通图:有向图中,若任意两点之间都存在一条有向路径,那么该图为强连通图。
    3)强连通分量:有向图的极大强连通子图称为有向图的强连通分量。(无向图称为连通分量和连通图,有向图称为强连通分量和强连通图。)

  3. 图的存储结构–邻接矩阵
    1)邻接矩阵:行、列各对应一个顶点,若行对应的顶点i到列对应的顶点j之间有弧相连,则A[i][j]=1,否则等于0,若为网(即每条弧都有其对应的权值),则A[i][j]=w,或无穷。(如图有n个点,则邻接矩阵是n*n阶的)

    2)无向网的临界矩阵存储代码:

typedef char VertexType;
#define INFINITY 32767 //无穷
#define MVNUM 100//最大顶点数

//弧的定义
typedef struct
{
   int adj;//邻接数,即若两点之间有边则为1,没有边则为0,如果是网,就是这条边上的权值
   InfoType *info;//弧的附加信息,到现在还没接触到有的,可以暂时不用考虑 
}ArcType;

//图的定义
typedef struct
{
   int vexnum,arcnum;//顶点数,边数
   VertexType vexs[MVNU];//存边需要先知道有哪些点
   ArcType arcs[MVNUM][MVNUM];//弧是用来存边的,边用两个顶点来表示,需要用二维数组
}MGraph;


//以创建无向网为例,给出代码
Status CreatUDN(MGraph &G)
{
    scanf("%d%d",&G.vexnum,&G.arcnum);//输入顶点数和边数(如果弧有附加信息,则需要再输入附加信息)
    for(int i = 0;i < G.vexnum;++i)
    {
        scanf("%c",&G.vexs[i]);//输入各个顶点
        //先将各条边的权值初始化为无穷大
        for(int j = 0; j < G.arcs; ++j)
        {
            G.vexs[i][j] = INFINITY;
        }
    }

    for(int k = 0;k < G.arcnum; ++k)
    {
        char u,v;
        int w;
        scanf("%c%c%d",&u,&v,&w);//输入两个顶点和该条边的权值
        //因为输入的点是字符型的,所以要先在图中找到其对应的下标

        int i = LocateVex(G,u);
        int j = LocateVex(G,v);//u,v对应的下标分别是i和j
        G.arcs[i][j] = w;
        G.arcs[j][i] = w;//因为是无向网,所以一条边,既是ij,也是ji

    }
}
3)邻接矩阵存储的优缺点:邻接矩阵存储,易求顶点的度,邻接点,易判断两点之间是否有边或弧相连,但是不利于稀疏图的存储,较浪费空间。

4.图的存储结构–邻接表
1)邻接表:一个顶点数组,每个顶点对应着它所有的邻接点。
2)以有向网为例,建立邻接表,给出代码


//以有向网为例,给出邻接表的代码
typedef char VertexType;
#define INFINITY 32767 //无穷
#define MVNUM 100//最大顶点数

//弧的定义
typedef struct ArcNode
{
    int adjvex;
    struct ArcNode *nextarc;
    InfoType* info;//弧的附加信息,可以暂时不考虑
}ArcNode;

typedef struct VexNode
{
    char data;
    ArcNode *firstarc;
}VexNode,AdjList[MVNUM];
typedef struct
{
    int vexnum,arcnum;//图的顶点数,边数
    AdjList vertices;//
}MGraph;

Status CreatDN(MGraph &G)
{
    scanf("%d%d",&G.vexnum,&G.arcnum);
    for(int i = 0; i < G.vexnum; ++i)
    {
        scanf("%c",&G.vertices[i].data);//输入各个顶点
        G.vertices[i].firstarc = NULL;//将各个顶点的第一条边初始化为空
    }

    for(int i = 0;i < G.arcnum; ++i)
    {
        char u,v;
        int w;
        scanf("%c%c%d",&u,&v,&w);//输入一条"边"和它的权值
        int i = LocateVex(G,u);
        int j = LocateVex(G,v);//输入的点是字符型的,需要在图里面找到它对应的下标
        ArcNode arc = (ArcNode*)malloc(sizeof(ArcNode));//因为下面需要将该边放到第一条边的位置上,所以这里定义一条边,便于操作
        arc.adjvex = j;
        arc.nextarc = G.vertices[i].firstarc;//将该边放到第一条边的位置上
        G.vertices[i].firstarc = arc;
    }

    return OK;
}
 3)无向图建立邻接表,需要n个头结点(有n个点),2e个边节点(2e条边)
 4)邻接表存储的优缺点:对于有向图,易求点的出度和邻接点,但是不容易求入度。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值