图的存储-邻接表

图的邻接表之前实现的时候,一直有点小问题

现在才明白 原来头结点是有内容的,之前一直当做一个标志位置来使用

说到底,这就是一种顺式和链式相互结合的储存结构

但还是不知其所以然,这个结构相较于邻接矩阵除了空间储存上面有很大优势,还有访问邻接节点方便

不明白他还有什么非他不可的理由

(其实就是因为自己对链式结构操作不是很熟悉找了个借口。)

邻接表(Adjacency List)是图的一种顺序存储与链式存储结合的存储方法。邻接表表示法类似于树的孩子链表表示法。就是对于图G 中的每个顶点vi,将所有邻接于vi
的顶点vj 链成一个单链表,这个单链表就称为顶点vi 的邻接表,再将所有点的邻接表表头放到数组中,就构成了图的邻接表。在邻接表表示中有两种结点结构

一种是顶点表的结点结构,它由顶点域(vertex)和指向第一条邻接边的指针域(firstedge)构成,另一种是边表(即邻接表)结点,它由邻接点域(adjvex)和指向下一条邻接边的指针域(next)构成。对于网图的边表需再增设一个存储边上信息(如权值等)的域(info),网图的边表结构如图8.10
所示。

邻接表表示的形式描述如下:

#define MaxVerNum 100 /*最大顶点数为100*/

typedef struct node{ /*边表结点*/
	int adjvex; /*邻接点域*/
	struct node * next; /*指向下一个邻接点的指针域*/
	/*若要表示边上信息,则应增加一个数据域info*/
}EdgeNode;

typedef struct vnode{ /*顶点表结点*/
	VertexType vertex; /*顶点域*/
	EdgeNode * firstedge; /*边表头指针*/
}VertexNode;

typedef VertexNode AdjList[MaxVertexNum]; /*AdjList 是邻接表类型*/

typedef struct{
	AdjList adjlist; /*邻接表*/
	int n,e; /*顶点数和边数*/
}ALGraph; /*ALGraph 是以邻接表方式存储的图类型*/

建立一个有向图的邻接表存储的算法如下:

void CreateALGraph(ALGraph *G)
{/*建立有向图的邻接表存储*/
	int i,j,k;
	EdgeNode * s;

	printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");
	scanf("%d,%d",&(G->n),&(G->e)); /*读入顶点数和边数*/
	printf("请输入顶点信息(输入格式为:顶点号<CR>):\n");

	for (i=0;i<G->n;i++) /*建立有n 个顶点的顶点表*/
	{
	scanf("\n%c",&(G->adjlist[i].vertex)); /*读入顶点信息*/
	G->adjlist[i].firstedge=NULL; /*顶点的边表头指针设为空*/
	}

	printf("请输入边的信息(输入格式为:i,j):\n");

	for (k=0;k<G->e;k++) /*建立边表*/
	{scanf("\n%d,%d",&i,&j); /*读入边<Vi,Vj>的顶点对应序号*/
	s=(EdgeNode*)malloc(sizeof(EdgeNode)); /*生成新边表结点s*/
	s->adjvex=j; /*邻接点序号为j*/
	s->next=G->adjlist[i].firstedge; /*将新边表结点s 插入到顶点Vi 的边表头部*/
	G->adjlist[i].firstedge=s;
	}
}/*CreateALGraph*/

若无向图中有n 个顶点、e 条边,则它的邻接表需n 个头结点和2e 个表结点。显然,在边稀疏(e<<n(n-1)/2)的情况下,用邻接表表示图比邻接矩阵节省存储空间,当和边相关的信息较多时更是如此。

在无向图的邻接表中,顶点vi 的度恰为第i 个链表中的结点数;而在有向图中,第i个链表中的结点个数只是顶点vi 的出度,为求入度,必须遍历整个邻接表。在所有链表中其邻接点域的值为i
的结点的个数是顶点vi 的入度。有时,为了便于确定顶点的入度或以顶点vi 为头的弧,可以建立一个有向图的逆邻接表,即对每个顶点vi 建立一个链接以vi为头的弧的链表。例如图8.12 所示为有向图G2(图8.2)的邻接表和逆邻接表。

在建立邻接表或逆邻接表时,若输入的顶点信息即为顶点的编号,则建立邻接表的复杂度为O(n+e),否则,需要通过查找才能得到顶点在图中位置,则时间复杂度为O(n·e)。

在邻接表上容易找到任一顶点的第一个邻接点和下一个邻接点,但要判定任意两个顶点(vi 和vj)之间是否有边或弧相连,则需搜索第i 个或第j 个链表,因此,不及邻接矩阵方便。

时间: 2024-12-14 02:16:58

图的存储-邻接表的相关文章

数据结构:图的实现--邻接表

使用邻接表实现图结构 当图中的边数较少时,用邻接表来实现图结构,则会浪费很多内存空间.因此,考虑另一种实现图结构的方法:邻接表.在邻接表中主要有两种节点结构体: 顶点节点 边节点 直接看代码 类定义 #include<iostream> #include<iomanip> using namespace std; //最大权值 #define MAXWEIGHT 100 //边节点 typedef struct edgenode_tag { int adjvex; //邻接点 in

图的建立——邻接表表示(C语言+VC6.0平台)

图是一种重要而且相对复杂的数据结构,在实际编程中非常有用.邻接表是图的主要表示形式之一,是一种链接表表示方法. #include<stdio.h> #include<stdlib.h> #define MAX 10//令图的最大顶点个数为10 typedef struct node//边表结点(弧) { int adjvex;//相连顶点的编号 int weight;//边权 struct node *pnext;//指向下一个边表结点 }edgenode; typedef str

图的创建——邻接表法

顶点表 + 边表 // 前者是数组,后者是单链表 #include <iostream> #include <cstdio> #include <cstdlib> using namespace std; const int VERTEX_NUM = 20; // 最大允许的顶点数 // 边表的结点(单链表) class EdgeNode { public: int vertexData; int weight; EdgeNode *next; }; // 顶点表的结点

数据结构-图存储表示之邻接表

邻接表 在图论中,邻接表代表一个图中的所有边或弧. 邻接表存储表示,需要保存一个顺序存储的顶点表和每个顶点上的边的链接表. 邻接表(Adjacency List),即数组与链表相结合的存储方法. 如果是无向图,那么每条边由两个结点组成,分别代表边的两个端点: 如果是有向图,那么每条边是一个结点对,分别代表边的始点和终点. 一般来说,邻接表是无向的. 在计算机科学中,邻接表描述一种紧密相关的数据结构,用于表征图.在邻接表的表示中,对于图中的每个顶点,我们将保存所有其它与之相连的顶点(即"邻接表&q

数据结构实践——操作用邻接表存储的图

本文是针对[数据结构基础系列(7):图]的实践. [项目 - 操作用邻接表存储的图] 假设图G采用邻接表存储,分别设计实现以下要求的算法: (1)输出出图G中每个顶点的出度: (2)求出图G中出度最大的一个顶点,输出该顶点编号: (3)计算图G中出度为0的顶点数: (4)判断图G中是否存在边<i,j>. 利用下图作为测试用图,输出结果. 提示:(1)分别设计函数实现算法:(2)不要全部实现完再测试,而是实现一个,测试一个:(3)请利用图算法库. [参考解答] #include <stdi

图的存储结构之邻接表

邻接矩阵的缺点:边数相对顶点较少的图,极大地浪费了存储空间. 把数组与链表相结合的存储方法称为邻接表.(Adjacency List) 邻接表的处理办法: 顶点用一个一维数组存储(较容易读取顶点信息),每个数据元素还需要存储指向第一个邻接点的指针,以便于查找该顶点的边信息. 每个顶点的所有邻接点构成一个线性表(用单链表存储).无向图称为顶点Vi的边表,有向图称为顶点Vi作为弧尾的出边表. 图1  无向图的邻接表结构 data是数据域,存储顶点的信息,firstedge是指针域,指向边表的第一个结

图的邻接表表示与无环图的拓扑排序

一.  图的最常用的表示方法是邻接矩阵和邻接表. 1,邻接矩阵 邻接矩阵其实就是一个二维数组,对于每条边<u,v>,我们就令A[u][v] = 1,如果图为有权图,我们也可以令A[u][v]等于该权,这么表示的优点是非常简单,但是它的空间需求很大,如果图是稠密的,邻接矩阵是合适的表示方法,如果图是稀疏的,那这种方法就太浪费空间了,下面给出图的邻接矩阵表示例子. 2 邻接表 邻接表是图的常用储存结构之一.邻接表由表头结点和表结点两部分组成,其中图中每个顶点均对应一个存储在数组中的表头结点.如下图

图的邻接表

邻接矩阵和邻接表区别: 对于n个顶点,m条边,对于n阶有向完全图最大的m=2*( n-1+(n-2)+(n-3)+...+2+1 )= O(n^2) ,当边数远小于n^2的稀疏图来说用邻接表储存图的空间时间复杂度是O(M),而邻接矩阵储存是O(N^2). 邻接表的两种实现方式: 1.用数组实现: int u[ ],v[ ],w[ ];    //分别储存u点,v点,和边权值. int first[ n+1 ];   //下标表示1,2,....,n点,储存着各个点目前时间最后读入的一条边.所以一

看数据结构写代码(36) 图的邻接表表示与实现

图的邻接表表示法,是为每一个顶点建立一个链表,链表里存放着相同弧尾的 弧的信息,这些链表顺序存放在数组中.下面是无向图g2的邻接表 邻接表 比 邻接矩阵 节省空间,同时 也带来一些操作上的 不便,例如 看 两个顶点是否 相邻,需要 遍历 链表,在 求 无向图顶点的度时,只需 遍历 顶点的链表,而 求 有向图 顶点的度 需要 遍历 整个图 查找 弧头 为这个顶点的 个数. 如果 不想这样做,可以 建立 逆邻接表,即 链表里 存放着 相同 弧头的 弧 的信息. 下一节 要说的 十字链表 类似于这种结