图 (中)

来源:互联网 发布:幼儿园美工室活动记录 编辑:程序博客网 时间:2024/06/09 18:38

图的存储

邻接矩阵

考虑到图是由顶点和边(弧)两部分组成,那就分成两部分存储。

图的邻接矩阵存储方式是用两个数组表示图,一个一维数组存储图中的顶点信息,一个二维数组(称为邻接矩阵)存储图中的边或者弧的信息。

设图G中有n个顶点,则邻接矩阵是一个n×n 的方阵,定义为

arc[i][j]={1,0,(vi,vj)E<vi,vj>E

实际举例:

无向图:

顶点数组:

A B C D

边数组:

ABCDA0101B1011C0101D1110

特点:

  1. 无向图的邻接矩阵是一个对称矩阵。主对角线(左上角–>右下角)上线的元素是相等的。
  2. 某个顶点的度等于第i行的元素之和.B的度是1+0+1+1=3 度为3
  3. 顶点i的所有邻接点就是第i行的元素中为1的点.

有向图:

顶点数组:

A B C D

边数组:

ABCDA0000B1000C1000D0110

有向图的邻接矩阵一般不是对称的。

网图

每条边上带权的图叫做网

如何存储

arc[i][j]=Wij,0,,(vi,vj)E<vi,vj>Ei==j

这里的wij表示权值,表示一个计算机允许的、大于所有边上权值的值,也就是一个不可能的值。一般表示不可达。

顶点数组:

A B C D

边数组:

ABCDA0B60C90D780

代码实现:

#include <stdio.h>typedef char VertexType; /*顶点的数据类型*/typedef int EdgeType; /*权值类型*/#define MAXVEX 100 /*最大定点数*/#define INFINITY 65535 /*不可达*/typedef struct Graph{    VertexType vesx[MAXVEX]; // 定点表    EdgeType arc[MAXVEX][MAXVEX]; //邻接矩阵    int numVertexs; //当前的定点数    int numEdges; //当前的边数}Graph;/** * @author 韦轩 * @time 2015/08/30 * @brief 邻接矩阵创建无向图 * @param G  * @return */void createUdGraph(Graph* G){    printf("Input the vertexts and the edges :\n");    scanf_s("%d,%d", &G->numVertexs, &G->numEdges);    int i, j, w;    for (i = 0; i < G->numVertexs;i++)    {        scanf_s(&G->vesx[i]);    }    for (i = 0; i < G->numEdges; i++)    {        for (j = 0; j < G->numVertexs;j++)        {            G->arc[i][j] = INFINITY;//初始化        }    }    for (int k = 0; k < G->numEdges;k++)    {        printf("Input the (Vi,Vj) and the weight :\n");        scanf_s("%d,%d,%d", &i, &j, &w);        G->arc[i][j] = w;        G->arc[j][i] = G->arc[i][j];    }}

可以看出,N个顶点和E条边的无向图的创建,时间复杂度是
O(N+N2+E),其中邻接矩阵的初始化,需要O(N2)

邻接表

当边数比较少的时候,邻接矩阵对空间的浪费比较严重.

为了避免空间浪费的问题,引入了邻接表的方式:数组与链表相结合的存储方法称为邻接表(Adjacency List)

处理办法:

顶点表:图中的顶点使用一个一维数组存储,为每一个还需要存储一个指向第一个邻接点的指针。

图中的每个顶点Vi的所有邻接点构成一个线性表,使用单链表存储。

无向图:

邻接表

顶点表的的各个结点由data域和firstedge两个域组成,data是数据域,存储节点信息,firstedge是指针域,指向边表的第一个结点,即此节点的第一个邻接点。

边表结点有adjvex和next指针域组成,adjvex是邻接点域,存储某顶点的邻接点在定点表中的下标。next则指向边表中下一个结点的指针。

有向图:

带权:

在边表结点增加weight数据域

代码实现

#include <stdio.h>#include <malloc.h>typedef char VertexType;typedef int EdgeType; //权值类型#define MAXVEX 100/** * @author 韦轩 * @time 2015/08/30 * @brief 边表结点 *   */typedef struct EdgeNode{    int adhvex; //邻接点域,存储该顶点对应的下标    EdgeType weight;//权值    struct EdgeNode* next;//指针域,指向下一个邻接点}EdgeNode;/** * @author 韦轩 * @time 2015/08/30 * @brief 顶点表结点 */typedef struct VertexNode{    VertexType data; //顶点域,存储顶点信息    EdgeNode* firstedge; //边表头指针}VertexNode, AdjList[MAXVEX];/** * @author 韦轩 * @time 2015/08/30 * @brief 图 */typedef struct GraphAdjList{    AdjList adjList;     int numVertexs; //当前的顶点数    int numEdges; //当前的边数}GraphAdjList;void creatGraph(GraphAdjList* G){    int i, j, k;    EdgeNode* edgeNode;    printf("Input the vertexs and edges:\n");    scanf_s("%d,%d", &G->numVertexs, &G->numEdges);    /*        读入顶点信息,建立顶点表    */    for (i = 0; i < G->numVertexs;i++)    {        scanf_s(&G->adjList[i].data);        G->adjList[i].firstedge = NULL;//边表置为空表    }    for (k = 0; k < G->numEdges;k++)    {        printf("Input the vi vj:\n");        scanf_s("%d,%d", &i, &j);        edgeNode = (EdgeNode*)malloc(sizeof(EdgeNode));//分配内存        /*            生成边表结点        */        edgeNode->adhvex = j;//邻接序号为j        /*            将edgeNode指针指向当前顶点指向的结点        */        edgeNode->next = G->adjList[i].firstedge;        /*            将当前顶点的指针指向edgeNode        */        G->adjList[i].firstedge = edgeNode;        edgeNode = (EdgeNode*)malloc(sizeof(EdgeNode));//分配内存        edgeNode->adhvex = i;        edgeNode->next = G->adjList[j].firstedge;        /*        将当前顶点的指针指向edgeNode        */        G->adjList[j].firstedge = edgeNode;    }}

可以看出,N个顶点和E条边的无向图的创建,时间复杂度是
O(N+E)

十字链表

邻接多重表

边集数组

0 0
原创粉丝点击