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

来源:互联网 发布:ping ip加端口怎么写 编辑:程序博客网 时间:2024/06/06 03:29
  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)邻接表存储的优缺点:对于有向图,易求点的出度和邻接点,但是不容易求入度。
原创粉丝点击