图->存储结构->邻接表
文字描述
邻接表是图的一种链式存储结构。在邻接表中,对图中每个顶点建立一个单链表,第i个单链表的结点表示依附顶点vi的边(对有向图是指以顶点vi为尾的弧)。单链表中的每个结点由3个域组成,其中邻接点域adjvex指示与顶点vi邻接的点在图中的位置;链域nextarc指示下一条边或弧的结点;数据域info存储和边或弧相关的信息如权值等。每个链表上附设一个表头结点,在表头结点中,除了设有链域firstarc指向链表中第一个结点外,还设有存储顶点vi的名或其他有关信息的数据域data。
在无向图的邻接表中,顶点vi的度恰为第i个单链表中的结点数;而在有向图中,第i个链表中的结点数只是顶点vi的出度,为求入度,需便历整个邻接表;为了方便确定顶点的入度或以顶点vi为头的弧,可以建立一个有向图的逆邻接表,即对每个顶点vi建立一个了链接以vi为头的弧的表。

示意图


算法分析
在建立邻接表或逆邻接表时,若输入的顶点信息就是顶点的编号,则建立邻接表的时间复杂度为n+e;否则,需要通过查找才能得到顶点在图中位置,则时间复杂度为n*e.
在邻接表上容易找到任一顶点的第一个邻接点和下一个领接点,但要判定任意两个顶点(vi和vj)之间是否有边或弧相连,则需搜索第i个或第j个链表;因此,不及邻接矩阵方便。
代码实现
/*
以邻接表作为图的存储结构创建图。
*/ #include <stdio.h>
#include <stdlib.h>
#include <string.h> #define INFINITY 100000 //最大值
#define MAX_VERTEX_NUM 20 //最大顶点数
#define None -1
typedef enum {DG, DN, UDG, UDN} GraphKind; //{有向图,有向网,无向图,无向网}
typedef char VertexType;
typedef struct{
char note[];
}InfoType;
//表结点
typedef struct ArcNode{
int adjvex; //该弧所指向的顶点的位置
struct ArcNode *nextarc; //指向下一条弧的指针
InfoType *info; //该弧相关信息的指针
}ArcNode;
//头结点
typedef struct VNode{
VertexType data;//顶点信息
ArcNode *firstarc;//指向第一条依附该顶点的弧的指针
}VNode, AdjList[MAX_VERTEX_NUM];
typedef struct{
AdjList vertices;
int vexnum;//图的顶点数
int arcnum;//图的弧数
int kind; //图的种类标志
}ALGraph; /*
若G中存在顶点u,则返回该顶点在图中位置;否则返回-1。
*/
int LocateVex(ALGraph G, VertexType v)
{
int i = ;
for(i=; i<G.vexnum; i++){
if(G.vertices[i].data == v){
return i;
}
}
return -;
} /*
在链表L的头部前插入v
*/
int InsFirst(ArcNode *L, int v)
{
ArcNode *n = (ArcNode *)malloc(sizeof(struct ArcNode));
n->adjvex = v;
n->nextarc = L->nextarc;
L->nextarc = n;
return ;
} /*
采用邻接表的存储结构,构造无向图
*/
int CreateUDG(ALGraph *G)
{
int i = , j = , k = , IncInfo = ;
int v1 = , v2 = ;
char tmp[] = {}; printf("输入顶点数,弧数,其他信息标志位: ");
scanf("%d,%d,%d", &G->vexnum, &G->arcnum, &IncInfo); for(i=; i<G->vexnum; i++){
printf("输入第%d个顶点: ", i+);
memset(tmp, , sizeof(tmp));
scanf("%s", tmp);
G->vertices[i].data = tmp[];
G->vertices[i].firstarc = malloc(sizeof(struct ArcNode));
G->vertices[i].firstarc->adjvex = None;
G->vertices[i].firstarc->nextarc = NULL;
} for(k=; k<G->arcnum; k++){
printf("输入第%d条弧(顶点1, 顶点2): ", k+);
memset(tmp, , sizeof(tmp));
scanf("%s", tmp);
sscanf(tmp, "%c,%c", &v1, &v2);
i = LocateVex(*G, v1);
j = LocateVex(*G, v2);
InsFirst(G->vertices[i].firstarc, j);
InsFirst(G->vertices[j].firstarc, i);
if(IncInfo){
//other info on arc
}
}
return ;
} /*
采用邻接表的存储结构,构造图
*/
int CreateGraph(ALGraph *G)
{
printf("输入图类型: -有向图(0), -有向网(1), +无向图(2), -无向网(3): ");
scanf("%d", &G->kind);
switch(G->kind){
case DG:
case DN:
case UDN:
printf("还不支持!\n");
return -;
case UDG:
return CreateUDG(G);
default:
return -;
}
} /*
输出图的信息
*/
void printG(ALGraph G)
{
if(G.kind == DG){
printf("类型:有向图;顶点数 %d, 弧数 %d\n", G.vexnum, G.arcnum);
}else if(G.kind == DN){
printf("类型:有向网;顶点数 %d, 弧数 %d\n", G.vexnum, G.arcnum);
}else if(G.kind == UDG){
printf("类型:无向图;顶点数 %d, 弧数 %d\n", G.vexnum, G.arcnum);
}else if(G.kind == UDN){
printf("类型:无向网;顶点数 %d, 弧数 %d\n", G.vexnum, G.arcnum);
}
int i = ;
ArcNode *p = NULL;
for(i=; i<G.vexnum; i++){
printf("%c\t", G.vertices[i].data);
p = G.vertices[i].firstarc;
while(p){
if(p->adjvex != None)
printf("%d\t", p->adjvex);
p = p->nextarc;
}
printf("\n");
}
return;
} int main(int argc, char *argv[])
{
ALGraph G;
if(CreateGraph(&G) > -){
printG(G);
}
return ;
}
邻接表存储结构(图)
代码运行

图->存储结构->邻接表的更多相关文章
- 图->存储结构->邻接多重表
文字描述 邻接多重表是无向图的另一种链式存储结构. 虽然邻接表是无向图的一种很有效的存储结构,在邻接表中容易求得顶点和边的各种信息. 但是,在邻接表中每一条边(vi,vj)有两个结点,分别在第i个和第 ...
- 图的bfs遍历模板(邻接矩阵存储和邻接表存储)
bfs遍历图模板伪代码: bfs(u){ //遍历u所在的连通块 queue q; //将u入队 inq[u] = true; while (q非空){ //取出q的队首元素u进行访问 for (从u ...
- 图->存储结构->十字链表
文字描述 十字链表是有向图的另一种链式存储结构. 在十字链表中,对应于有向图中每一条弧有一个结点,对应于每个顶点也有一个结点.这些结点的结构如下所示: 在弧结点中有5个域: 尾域tailvex和头域h ...
- 图->存储结构->数组表示法(邻接矩阵)
文字描述 用两个数组分别存储顶点信息和边/弧信息. 示意图 算法分析 构造一个采用邻接矩阵作存储结构.具有n个顶点和e条边的无向网(图)G的时间复杂度是(n*n + e*n), 其中对邻接矩阵G.ar ...
- 图的建立——邻接表表示(C语言+VC6.0平台)
图是一种重要而且相对复杂的数据结构,在实际编程中非常有用.邻接表是图的主要表示形式之一,是一种链接表表示方法. #include<stdio.h> #include<stdlib.h ...
- 数据结构与算法之PHP用邻接表、邻接矩阵实现图的广度优先遍历(BFS)
一.基本思想 1)从图中的某个顶点V出发访问并记录: 2)依次访问V的所有邻接顶点: 3)分别从这些邻接点出发,依次访问它们的未被访问过的邻接点,直到图中所有已被访问过的顶点的邻接点都被访问到. 4) ...
- 数据结构之---C语言实现图的邻接表存储表示
// 图的数组(邻接矩阵)存储表示 #include <stdio.h> #include <stdlib.h> #include <string.h> #defi ...
- 图的dfs遍历模板(邻接表和邻接矩阵存储)
我们做算法题的目的是解决问题,完成任务,而不是创造算法,解题的过程是利用算法的过程而不是创造算法的过程,我们不能不能陷入这样的认识误区.而想要快速高效的利用算法解决算法题,积累算法模板就很重要,利用模 ...
- 图的存储结构与操作--C语言实现
图(graph)是一种比树结构还要复杂的数据结构,它的术语,存储方式,遍历方式,用途都比较广,所以如果想要一次性完成所有的代码,那代码会非常长.所以,我将分两次来完成图的代码.这一次,我会完成图的五种 ...
随机推荐
- 【Android】Eclipse快捷键精选
1. ctrl+shift+r:打开资源 这可能是所有快捷键组合中最省时间的了. 这组快捷键可以让你打开你的工作区中任何一个文件,而你只需要按下文件名或mask名中的前几个字母,比如applic*.x ...
- 安装 Xshell 5/6 时出现.dll以及0xc000007错误的解决
安装 Xshell 5/6 时出现.dll以及0xc000007错误的解决 问题:缺少 mfc110.dll或者是其他.dll文件以及应用程序运行错误,如下所示. 方法: 一种是网上直接下载.(缺少. ...
- bootstrap学习-初步使用介绍
准备 下载Bootstrap https://github.com/twbs/bootstrap/releases/download/v3.3.6/bootstrap-3.3.6-dist.zip h ...
- Java如何根据主机名(域名)获取IP地址?
在Java编程中,如何根据主机名(域名)获取IP地址? 以下示例显示了如何通过net.InetAddress类的InetAddress.getByName()方法将主机名更改为指定的IP地址. pac ...
- session一直报错Session store not set on request
Route::group(['middleware' => ['web']], function () { //});仍然报错,看了 session是使用默认file,没问题:app/stora ...
- [PGM] Temporal Models
这里的一些东西只是将过去已有的东西用PGM解释了一遍,但优势还是明显的,对整体认识有帮助. Video: https://www.youtube.com/watch?v=ogs4Oj8KahQ& ...
- [Artoolkit] ARSimpleNativeCarsProj for Multi Markers Tracking
效果简直了,但代码架构有点坑,慢慢道来. libc++_shared.so应该是c++的库:libARWrapperNativeCaresExample.so也有对应的c++文件:那么,libARWr ...
- Mac 环境 Vue 开发 CPU 占用率高 问题
Mac开发Vue应用时,发现CPU风扇转的老高. htop查看一下: 问题找到了,就是这个dev-server.js,node起的进程. 然后就是 dtruss -p 1230(进程ID) 命名跟踪一 ...
- java调用删除文件的方法删除文件,却删除不干净
场景: 程序中在做数据下载时,生成了一个临时文件夹.夹子里面有一些txt和其他格式文件. 数据下载完毕后,需要删除这个临时文件夹,但是一直删除不干净,总会有一下文件残留. 网搜到了这个问题的原因: 内 ...
- 删除新版UniAccess Agent 办公室监控软件的方法
UniAccess Agent 是在由LeagSoft开发的监控软件,老版本的一般安装在C:\Program Files\LeagSoft\UniAccess Agent这个目录下,一般找到这个目录点 ...