图 Graph

图的存储结构:邻接矩阵与邻接表
本文介绍了图的两种常见存储结构——邻接矩阵和邻接表,详细阐述了它们的实现方式。邻接矩阵适用于表示图中任意两个顶点间是否存在边,而邻接表通过链表节省空间,尤其适合稀疏图。十字链表则是邻接表的一种优化,分别存储入边和出边。此外,对于带权图,还额外添加了 weight 域来存储权值。

图的邻接矩阵存储结构:

typedef char VertexType;
typedef int EdgeType;
#define MaxVex 100
#define Infinity 65535
typedef struct
{
	VertexType vexs[MaxVex];
	EdgeType arc[MaxVex][MaxVex];
	int numVertexes, numEdges;
} MGraph;

图的邻接表存储结构:

#define Maxvex 100
typedef char VexType;               /*  顶点类型应由用户定义  */
typedef int EdgeType;              /*  边上的权值类型应由用户定义  */

typedef struct EdgeNode            /*  边表结点  */
{
    int adjvex;         		   /*  邻接点域,存储该顶点对应的下标  */
    EdgeType weight;				/*  用于存储权值,对于非网图可以不需要  */
    struct EdgeNode *next;         /*  链域,指向下一个邻接点  */
} EdgeNode;

typedef struct VexNode  		  /*  顶点表结点  */
{
    VexType data;			   		/*  顶点域,存储顶点信息  */
    EdgeNode *firstedge;            /*  边表头指针  */
} VexNode, AdjList[Maxvex];

typedef struct
{
    AdjList adjList;
    int numVexes, numEdges;       /*  图中当前顶点数和边数  */
} GraphAdjList;

十字链表:
我们重新定义顶点表结点结构:
| data | firstin | firstout |
其中 firstin 表示入边表头指针,指向该顶点的入边表中的第一个结点;firstout 表示出边表头指针,指向该顶点的出边表的第一个结点。

我们重新定义边表结点结构:
| tailvex | headvex | headlink | taillink |
其中 tailvex 是指弧起点在顶点表的下标,headvex 是指弧终点在顶点表中的下标;headlink 是指入边表指针域,指向终点相同的下一条边;taillink 是指边表指针域,指向起点相同的下一条边。

如果是网,还可以再增加一个 weight 域来存储权值。

创建邻接矩阵的图:

    void CreateMGraph(MGraph *G)
    {
        int i,j,k,w;
        printf("输入顶点数和边数:\n");
        scanf("%d,%d,%d,%d", &G->numVertexes,&G->numEdges);
        for (i = 0; i < G->numVertexes; i++)
            scanf(&G->vexs[i]);
        for (i = 0; i < G->numVertexes; i++)
            for (j = 0; j < G->numVertexes; j++)
                G->arc[i][j] = Infinity;
        for (k = 0; k < G->numEdges; k++)
        {
            printf("输入边(vi,vj)上的下标i,下标j,权w:\n")
            scanf("%d, %d, %d", &i, &j, &w);
            G->arc[i][j] = w;
            G->arc[i][j] = G->arc[i][j];      //因为是无向图,矩阵对称
        }
    }

创建邻接表的图:
void CreateALGraph(GraphAdjList *G)
{
    int i,j,k;
    EdgeNode *e;
    printf("输入顶点数和边数:\n");
    scanf("%d,%d", &G->numVexes, &G->numEdges);
    for (i = 0; i< G->numVexes; i++)
    {
        scanf(&G->adjList[i]->data);
        G->adjList[i]->firstedge = NULL;
    }
    for (k = 0; k < G->numEdges; k++)
    {
        printf("输入边(vi,vj)上的顶点序号:\n");
        scanf("%d,%d",&i,&j);
        e = (EdgeNode *) malloc(sizeof(EdgeNode));
        
        e->adjvex = j;
        e->next = G->adjList[i]->firstedge;
        G->adjList[i]->firstedge = e;
        
        e = (EdgeNode *) malloc(sizeof(EdgeNode));
        
        e->adjvex = i;
        e->next = G->adjList[j]->firstedge;
        G->adjList[j]->firstedge = e;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值