图的邻接表

图的边数较少时,采用邻接矩阵存储图会浪费大量的空间。因此考虑把数组与链表结合在一次来存储,并提出了邻接表的概念。
关于无向图的邻接矩阵存储可参考我的上一篇博客

邻接表的处理方式:

1.图中顶点用一个一维数组存储,当然,顶点也可用单链表存储,不过数组可以更加方便地读取顶点信息。
2.图中每个顶点Vi的所有邻接点构成一个线性表,由于邻接点的个数不确定,所以选择用单链表来存储。

无向图邻接表结构如下图所示:
在这里插入图片描述code部分(无向图):

#include <stdio.h>
#include <stdlib.h>

//边数相对顶点较少的图采用邻接表的形式存储,这个邻接表的代码有问题
#define MAXVEX 100

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

typedef struct VertexNode		// 顶点表结点
{
	char data;					// 顶点域,存储顶点信息
	EdgeNode *firstEdge;		// 边表头指针
} VertexNode, AdjList[MAXVEX];

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

// 建立图的邻接表结构
void CreateALGraph(GraphAdjList *G)
{
	int i, j, k, w;
	EdgeNode *e;

	printf("请输入顶点数和边数:\n");
	scanf("%d %d", &G->numVertexes, &G->numEdges);

	// 读取顶点信息,建立顶点表
	for( i=0; i < G->numVertexes; i++ )
	{
		//scanf("%c", &G->adjList[i].data);
		G->adjList[i].data = 'a'+i;
		G->adjList[i].firstEdge = NULL;		// 初始化置为空表
	}
	for( k=0; k < G->numEdges; k++ )
	{
		printf("请输入边(Vi,Vj)上的顶点序号和边的权值,用空格隔开:\n");
		scanf("%d %d %d", &i, &j, &w);

		e = (EdgeNode *)malloc(sizeof(EdgeNode));
		e->adjvex = j;						// 邻接序号为j
		e->weight = w;
		e->next = G->adjList[i].firstEdge;
		G->adjList[i].firstEdge = e;

        //因为是无向图,彼此相对称
		e = (EdgeNode *)malloc(sizeof(EdgeNode));
		e->adjvex = i;						// 邻接序号为i
		e->weight = w;
		e->next = G->adjList[j].firstEdge;
		G->adjList[j].firstEdge = e;
	}
}

//打印邻接表
void PrintfGraphA(GraphAdjList G)
{
    for(int i = 0; i < G.numVertexes; i++)
    {
        printf("%d  %c\t", i,G.adjList[i].data);
        EdgeNode *p = G.adjList[i].firstEdge;
        while(p)
        {
            printf("%d %d\t", p->adjvex,p->weight);
            p = p->next;
        }
        printf("\n");
    }
}

int main()
{
    GraphAdjList G;
    CreateALGraph(&G);
    PrintfGraphA(G);
    return 0;
}

结果:
在这里插入图片描述

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

还是少年呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值