图的邻接矩阵和邻接表表示法

2024-06-16 05:32

本文主要是介绍图的邻接矩阵和邻接表表示法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

链表是一种线性存储结构,是一对一对应关系。而树是一种层次存储结构,是一对多的对应关系。而图则是一种关系存储结构,是多对多对应关系。树和图类似于数据库中的层次模型和关系模型。图的存储结构主要有两种,分别为邻接矩阵和邻接表法,其中邻接表较难,但本质相同,都是记录结点与其邻接结点,只是方法不同而已。下面分别讨论邻接表和邻接矩阵的思想。邻接表的思想是:定义三个结点,分别为表结点,头结点,邻接表结点,表结点存放与头结点相邻的结点序号,边的权值,以及下一个表结点。头结点中存放结点的真实值(char 或 int),和该结点的第一个邻接点。邻接表中存放的是头结点数组,结点数和边数。通过动态申请空间的方法给每个头结点创建邻接结点链表,这样就构造除了邻接表。而邻接矩阵则是通过采用一个邻接矩阵来记录邻接结点,当不相连时值为无穷大(自行定义的一个极大的数据)。在这里,我们规定:所讨论的图中任意两个结点之间最多有一条边,且无向图中顶点到其自身没有边(有向图可允许顶点到顶点有边),否则下面的算法会有相应的问题,(邻接矩阵就不可用了,邻接表就会有冗余数据了),下面是代码:

//图的存储结构
//邻接表
#include <stdio.h>
#include <stdlib.h>
#define Max 100 //顶点个数最多为100个
typedef char type;
typedef struct Arcnode{int index;int value;struct Arcnode *next;
}Arcnode,*parc;
typedef struct Node{type data;Arcnode *first;
}Node;
typedef struct Grap{Node nodetex[Max];int n; //顶点数int m; //边数
}Grap,*pgrap;
int Located(pgrap g,char ch){for(int i=0;i<g->n;i++)if(ch==g->nodetex[i].data)return i;
}
void Creat_grap(pgrap g){printf("输入图的结点数和边数:\n");scanf("%d%d",&g->n,&g->m);getchar();int i,index1,index2,value;char ch1,ch2;printf("输入各顶点:\n");for(i=0;i<g->n;i++){g->nodetex[i].data=getchar();g->nodetex[i].first=NULL;getchar();}printf("输入各边及权值:\n");	parc q;for(i=0;i<g->m;i++){scanf("%c,%c,%d",&ch1,&ch2,&value);getchar();index1=Located(g,ch1);index2=Located(g,ch2);q=(parc)malloc(sizeof(Arcnode));q->index=index2;q->value=value;q->next=g->nodetex[index1].first;g->nodetex[index1].first=q;//无向图(默认为任意两个顶点之间之多有一条边且自身到自身无边)/*q=(parc)malloc(sizeof(Arcnode));q->index=index1;q->value=value;q->next=g->nodetex[index2].first;g->nodetex[index2].first=q;*/}
}
void Show_grap(pgrap g){printf("图中各顶点的邻接顶点为:\n");for(int i=0;i<g->n;i++){printf("%c:",g->nodetex[i].data);parc q=g->nodetex[i].first;while(q){putchar(g->nodetex[q->index].data);q=q->next;}printf("\n");}
}
void Delete_grap(pgrap g){parc p,q;for(int i=0;i<g->n;i++){p=g->nodetex[i].first;while(p){q=p->next;free(p);p=q;}}
}
int main(){Grap g;pgrap p=&g;Creat_grap(p);Show_grap(p);Delete_grap(p);return 0;
}

测试数据://无向图

输入图的结点数和边数:
5 7
输入各顶点:
A
B
C
D
E
输入各边及权值:
A,B,20
A,C,10
B,D,50
A,D,40
B,E,60
C,D,30
D,E,70
图中各顶点的邻接顶点为:
A:DCB
B:EDA
C:DA
D:ECAB
E:DB




Terminated with return code 0
Press any key to continue ...


输入图的结点数和边数://有向图
4 6
输入各顶点:
A
B
C
D
输入各边及权值:
A,B,10
B,A,10
A,A,20
A,C,30
C,D,40
D,B,50
图中各顶点的邻接顶点为:
A:CAB
B:A
C:D
D:B

下面是邻接矩阵代码:

//图的邻接矩阵表示法
#include <stdio.h>
#include <stdlib.h>
#define Max 100
#define Inf 0x1111
typedef char type;
typedef struct Grap{type data[Max];int value[Max][Max];int n,m;
}Grap,*pgrap;
int Located(pgrap g,char ch){for(int i=0;i<g->n;i++)if(g->data[i]==ch)return i;
}
void Creat_grap(pgrap g){printf("输入图的顶点数和边数:\n");scanf("%d%d",&g->n,&g->m);//printf("ksgfdkj\n");getchar();printf("输入图中的顶点:\n");int i,j;for(i=0;i<g->n;i++){g->data[i]=getchar();getchar();}for(i=0;i<g->n;i++)for(j=0;j<g->n;j++)g->value[i][j]=Inf;printf("请输入图中的边:\n");int index1,index2,value;char ch1,ch2;while(g->m--){scanf("%c,%c,%d",&ch1,&ch2,&value);getchar();index1=Located(g,ch1);index2=Located(g,ch2);g->value[index1][index2]=value;//无向图//g->value[index2][index1]=value;}
}
void Show_grap(pgrap g){printf("邻接矩阵表示法个顶点的邻接顶点:\n");int i,j;for(i=0;i<g->n;i++){printf("%c:",g->data[i]);for(j=0;j<g->n;j++)if(g->value[i][j]!=Inf)putchar(g->data[j]);printf("\n");}
}
int main(){Grap g;pgrap p=&g;Creat_grap(p);Show_grap(p);return 0;
}

下面是测试数据://无向图

输入图的顶点数和边数:
5 7
输入图中的顶点:
A
B
C
D
E
请输入图中的边:
A,B,20
A,C,10
B,D,50
A,D,40
B,E,60
C,D,30
D,E,70
邻接矩阵表示法个顶点的邻接顶点:
A:BCD
B:ADE
C:AD
D:ABCE
E:BD

Terminated with return code 0
Press any key to continue ...


输入图的顶点数和边数: //有向图
4 6
输入图中的顶点:
A
B
C
D
请输入图中的边:
A,B,10
B,A,10
A,A,20
A,C,30
C,D,40
D,B,50
邻接矩阵表示法个顶点的邻接顶点:
A:ABC
B:A
C:D
D:B


Terminated with return code 0
Press any key to continue ...

这篇关于图的邻接矩阵和邻接表表示法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1065574

相关文章

C语言-数据结构 克鲁斯卡尔算法(Kruskal)邻接矩阵存储

相比普里姆算法来说,克鲁斯卡尔的想法是从边出发,不管是理解上还是实现上都更简单,实现思路:我们先把找到所有边存到一个边集数组里面,并进行升序排序,然后依次从里面取出每一条边,如果不存在回路,就说明可以取,否则就跳过去看下一条边。其中看是否是回路这个操作利用到了并查集,就是判断新加入的这条边的两个顶点是否在同一个集合中,如果在就说明产生回路,如果没在同一个集合那么说明没有回路可以加入

像素间的关系(邻接、连通、区域、边界、距离定义)

文章目录 像素的相邻像素4邻域D邻域8邻域 邻接、连通、区域和边界邻接类型连通区域边界 距离测度欧氏距离城市街区距离(city-block distance)棋盘距离(chessboard distance) 参考 像素的相邻像素 4邻域 坐标 ( x , y ) (x,y) (x,y)处的像素 p p p有2个水平的相邻像素和2个垂直的相邻像素,它们的坐标是: ( x

「图」邻接矩阵|边集数组|邻接表 / LeetCode 35|33|81(C++)

概述 我们开始入门图论:图的存储。 图是一种高级数据结构:链表是一个节点由一条边指向下一个节点,二叉树是一个节点由两条边指向下两个节点,而图是由任意多个节点由任意多条边指向任意多个节点。 图由节点和边构成,边往往存在边权。边权在不同的问题中往往有不同含义,如在最短路径中表示边的长度,在AOE网中表示任务所需时间。 对于这种复杂的结构,如何存储在计算机的程序语言中呢? 我们先来介绍三种存储

数据结构实验图论:基于邻接矩阵/邻接表的广度优先搜索遍历(BFS)

数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索(BFS)遍历,输出从某个顶点出发的遍历序列。(同一个结点的同层邻接点,节点编号小的优先遍历) 输入 输入第一行为整数n(0< n <100),表示数据的组数。 对于

图的广度优先搜索(BFS)算法与邻接矩阵表示

图的广度优先搜索(BFS)算法与邻接矩阵表示 1. 图的表示2. 广度优先搜索(BFS)BFS 算法步骤: 3. 使用邻接矩阵的 BFS 实现4. 运行时间分析时间复杂度:空间复杂度: 5. BFS 使用邻接列表与邻接矩阵的比较BFS 在邻接列表上的运行时间: 6. 结论 在计算机科学中,图是一种重要的数据结构,用于表示对象之间的复杂关系。图可以通过多种方式表示,包括邻接矩阵和邻接

判别以邻接表方式存储的有向图中是否存在由顶点vi到顶点vj的路径(i≠j)

试基于图的深度优先搜索策略写一算法,判别以邻接表方式存储的有向图中是否存在由顶点vi到顶点vj的路径(i≠j)。 注意:算法中涉及的图的基本操作必须在此存储结构上实现。 图的邻接表以及相关类型和辅助变量定义如下: Status visited[MAX_VERTEX_NUM];typedef char VertexType;typedef struct ArcNode {int adj

计算多图的等价无向图的邻接链表表示

计算多图的等价无向图的邻接链表表示 摘要:一、引言二、算法思路三、伪代码实现四、C代码实现五、算法分析六、结论 摘要: 在图论中,多图(Multigraph)是一种允许边重复以及存在自循环边(即一个顶点到其自身的边)的图。给定一个多图的邻接链表表示,本文旨在探讨如何构造一个等价的无向图,并给出其邻接链表表示。所谓等价的无向图,指的是在删除所有冗余的边和自循环边后,对于任意两个顶点

有向图的邻接表实现(Java版)

我是蚊子码农,欢饮您的关注。 一、有向图介绍 在无向图中,边没有方向性,就相当于一条公路,你可以来我这,我也可以去你那。 然而,现实世界里,有一些通道是单向的,只允许一个方向通过。 比如某些工作流程,你必须完成工作A,才能进行工作B。 这时候,我们需要用有向边,来表达这些数据。 当然,无向图可以看成特殊的有向图。 二、有向图的表达(思考部分) 我们知道,图是由结点集和边集构成的。其中,每一

(转)图算法单源最短路径Dijkstra算法(邻接表/邻接矩阵+优先队列STL)

一、前言   最短路径算法,顾名思义就是求解某点到某点的最短的距离、消耗、费用等等,有各种各样的描述,在地图上看,可以说是图上一个地点到达另外一个地点的最短的距离。比方说,我们把地图上的每一个城市想象成一个点,从一个城市到另一个城市的花费是不一样的。现在我们要从上海去往北京,需要考虑的是找到一条路线,使得从上海到北京的花费最小。有人可能首先会想到,飞机直达啊,这当然是时间消耗最小的方法,但是考虑

图深度优先搜索广度优先搜索,邻接表

#include <stdafx.h>#include"iostream"#include"malloc.h"using namespace std;#define MaxVertexNum 50 //定义最大顶点数typedef struct node{ //边表结点char adjvex; //邻接点域struct node *next; //