数据结构基础 之 通过邻接矩阵与邻接表 图 实现

【邻接矩阵】

邻接矩阵,就是一个反应边与边之间联系的二维数组。这个二维数组我们用matrix[numV][numV]表示,其中numV是顶点数。

对于无权图

若顶点Vi和Vj之间有边,则matrix[Vi][Vj]=1;否则matrix[Vi][Vj]=0。

对于有权图

若顶点Vi和Vj之间有边,且权值为weight,则matrix[Vi][Vj]=weight;否则matrix[Vi][Vj]=0或MAXWEIGHT(取最小权值或最大权值)。

【邻接表】

当图中的边数较少时,用邻接矩阵来实现图结构,则会浪费很多内存空间。因此,考虑另一种实现图结构的方法:邻接表。在邻接表中主要有两种节点结构体:

顶点节点(表示结点数据,也可以是节点下标(vertex),以及下一节点地址(next))

边节点(表示节点数据,也可以是节点下标(vertex),节点出度表(adjvex),以及出度表中下一节点地址(next))

【源码示例】

  • 邻接矩阵建图
void Graph::createGraph()

{

cout << "输入边数 ";

while (cin >> numE && numE < 0)

cout << "输入有误!,重新输入 ";

int i, j, w;

if (!isWeighted)  //无权图

{

if (!isDirected)  //无向图

{

cout << "输入每条边的起点和终点:\n";

for (int k = 0; k < numE; k++)

{

cin >> i >> j;

while (!check(i, j))

{

cout << "输入的边不对!重新输入\n";

cin >> i >> j;

}

matrix[i][j] = matrix[j][i] = 1;

}

}

else  //有向图

{

cout << "输入每条边的起点和终点:\n";

for (int k = 0; k < numE; k++)

{

cin >> i >> j;

while (!check(i, j))

{

cout << "输入的边不对!重新输入\n";

cin >> i >> j;

}

matrix[i][j] = 1;

}

}

}

else  //有权图

{

if (!isDirected)   //无向图

{

cout << "输入每条边的起点、终点和权值:\n";

for (int k = 0; k < numE; k++)

{

cin >> i >> j >> w;

while (!check(i, j, w))

{

cout << "输入的边不对!重新输入\n";

cin >> i >> j >> w;

}

matrix[i][j] = matrix[j][i] = w;

}

}

else  //有向图

{

cout << "输入每条边的起点、终点和权值:\n";

for (int k = 0; k < numE; k++)

{

cin >> i >> j >> w;

while (!check(i, j, w))

{

cout << "输入的边不对!重新输入\n";

cin >> i >> j >> w;

}

matrix[i][j] = w;

}

}

}

}

  • 邻接表建图
void Graph::createGraph()

{

//用一个新的变量表示边数,numE的修改则留到insertedge()中

int numEdge = 0;

cout << "输入边数 ";

while (cin >> numEdge && numEdge < 0)

cout << "输入有误!,重新输入 ";

int i, j, w;

if (!isWeighted)  //无权图

{

cout << "输入每条边的起点和终点:\n";

for (int k = 0; k < numEdge; k++)

{

cin >> i >> j;

while (!check(i, j))

{

cout << "输入的边不对!重新输入\n";

cin >> i >> j;

}

insertEdge(i, j);

}

}

else  //有权图

{

cout << "输入每条边的起点、终点和权值:\n";

for (int k = 0; k < numEdge; k++)

{

cin >> i >> j >> w;

while (!check(i, j, w))

{

cout << "输入的边不对!重新输入\n";

cin >> i >> j >> w;

}

insertEdge(i, j, w);

}

}

}

void Graph::insertEdge(int vertex, int adjvex, int weight)

{

insertedge(vertex, adjvex, weight);

if (!isDirected)  //无向图

insertedge(adjvex, vertex, weight);

}

void Graph::insertedge(int vertex, int adjvex, int weight)

{

EdgeNode *p, *q, *r;

p = q = r = NULL;

if (adjList[vertex].next)   //非第一个节点

{

p = adjList[vertex].next;

//移动p到合适位置

while (p && (p->adjvex < adjvex))

{

q = p;

p = p->next;

}

if (p && (p->adjvex == adjvex))  //修改已有边权值

p->weight = weight;

else

{

r = new EdgeNode;

r->adjvex = adjvex;

r->weight = weight;

r->next = p;

//当加入的新节点位于表的第一个位置

if (adjList[vertex].next == p)

adjList[vertex].next = r;

else

q->next = r;

numE++;

}

}

else

{

p = new EdgeNode;

p->adjvex = adjvex;

p->weight = weight;

p->next = NULL;

adjList[vertex].next = p;

numE++;

}

}

【详细源码详址】

http://blog.csdn.net/zhangxiangdavaid/article/details/38321327

http://blog.csdn.net/zhangxiangdavaid/article/details/38323593

【最后的话】

很明显的发现,邻接矩阵和邻接表一个是以矩阵数组的形式记录了图中边的关系,一个是以链表的形式记录边的关系。无它,链表肯定比数据更节省空间,但是,查找起来数据往往比链表更快捷。如果,还有兴趣可以用STL的list实现,这样将尽收二者之长,鉴于实现非常简单,此处代码就不再给出。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-29 05:20:28

数据结构基础 之 通过邻接矩阵与邻接表 图 实现的相关文章

数据结构之图(1)【邻接矩阵、邻接表】

邻接矩阵创建无向网: 图的邻接矩阵(Adjacency Matrix)存储方式是用两个数组来表示图.一个一维的数组存储图中顶点信息,一个二维数组(称为邻接矩阵)存储图中的边或弧的信息. 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 我们来看一个实例,图7-4-2的左图就是一个无向图. 我们再来看一个有向图样例,如图7-4-3所示的左图. 在图的术语中,我们提到了网的概念,也就是每条边上都带有权的图叫做网.那些这些权值就需要保存下来. 设图G是网图,有n个顶点,则邻接矩阵是一个n*n的

图的存储结构:邻接矩阵(邻接表)&amp;链式前向星

[概念]疏松图&稠密图: 疏松图指,点连接的边不多的图,反之(点连接的边多)则为稠密图. Tips:邻接矩阵与邻接表相比,疏松图多用邻接表,稠密图多用邻接矩阵. 邻接矩阵: 开一个二维数组graph[ ][ ]来记录图中点a与点b之间是否连通,初始化为0(或者-1之类的看情况):如果图中有可忽略的重边(如 只需重边中的最小边或最大边),则保存需要的那条边的边权,但如果有无法忽略的重边,就一定不要用邻接矩阵. int graph[MAXN][MAXN]; void graphInit() { me

PAT1013. Battle Over Cities(邻接矩阵、邻接表分别dfs)

//采用不同的图存储结构结构邻接矩阵.邻接表分别dfs,我想我是寂寞了吧,应该试试并查集,看见可以用并查集的就用dfs,bfs代替......怕了并查集了 //邻接矩阵dfs #include<cstdio>#include<algorithm>using namespace std;const int maxn=1001;int g[maxn][maxn];int n,tmp;bool vis[maxn];void dfs(int v){ vis[v]=true; for(int

无向图的表示:邻接矩阵和邻接表

这里将一个无向图用邻接表和邻接矩阵表示. 输入:顶底个数n,图中的各个边(用两个顶点表示). 输出:这个无线图的邻接矩阵和邻接表,其中邻接表中的链接按元素大小升序排列. 先给出一个例子说明.假设有无向图如下,则其邻接矩阵和邻接表如提示框中所示(其实就是下面程序的输出). 下面是程序的代码: #include <stdio.h> #include <stdlib.h> //图的表示,输入节点个数和边,构造图的邻接矩阵和邻接表 //邻接表中的链表节点 struct vNode{ int

图的邻接矩阵与邻接表

一.如何创建邻接表和邻接矩阵? 如图,根据上图建立一个无向图的邻接矩阵和邻接表~ 输入的数据,第一行为两个整数n,e(0<n<=1000,0<e<=5000),表示有n个点和e条边,接下来的e行,每行包含2个整数,表示每条边所连接的两个点. 然后输出图.(无硬性要求) 输入数据: 5 81 01 21 32 32 43 43 04 0 输出数据(示例): 0->1->3->4->NULL1->0->2->3->NULL2->1-

重连通量的邻接矩阵和邻接表两种形式的求法

邻接矩阵: #include <cstdio> #include <cstring> #include <stack> using namespace std; #define min(a,b) a<b?a:b #define N 105 int dfn[N],low[N],mat[N][N],visit[N],tmpdfn,n; struct Edge{ int x,y; void print(){ printf("%d-%d\n",x,y)

基于邻接矩阵和邻接表的两种方法实现无向图的BFS和DFS

广度优先搜索(Breadth-First-Search)和深度优先搜索(Deep-First-Search)是搜索策略中最经常用到的两种方法,特别常用于图的搜索. BFS的思想: 从一个图的某一个顶点V0出发,首先访问和V0相邻的且未被访问过的顶点V1.V2.--Vn,然后依次访问与V1.V2--Vn相邻且未被访问的顶点.如此继续,找到所要找的顶点或者遍历完整个图.我们采用队列来存储访问过的节点. DFS的思想: 深度优先搜索所遵循的策略就是尽可能"深"的在图中进行搜索,对于图中某一个

图的两种存储(邻接矩阵和邻接表)和两种遍历(DFS和BFS)

图的表示有很多,形式不固定,我暂时先记录我已经懂了的,能写的两种即大多数人应该都知道的邻接矩阵和邻接表. 邻接矩阵: 这里的邻接矩阵和离散数学说的有一点不同,至少有向图的邻接矩阵不同(离散书上的有向图的邻接矩阵求法到是有点像求任意两点的最短路径的Floyd算法) 以上都是(我现有知识认为的)废话: 重点 : G : 表示图: Nv:表示图的点数: Ne:表示图的边数: 邻接矩阵 即是一个 Nv * Nv 的矩阵,矩阵是用来储存  权值的(如果是带权图且有边的话),如果是无权图的的话,如果两顶点有

图(网)的存储结构(数组存储表示即邻接矩阵、邻接表)

图(Graph)是一种非线性结构 图的特点(多对多),顶点之间的关系是任意的,图中任意两个顶点之间都可能相关,顶点的前驱和后继个数无限制. 图:数据元素间存在多对多关系的数据结构,加上一组基本操作构成的抽象数据类型. 图的基本术语 顶点:图中的数据元素. 弧:若 <v, w>∈VR,则 <v, w> 表示从 v 到 w 的一条弧,且称 v 为弧尾,称 w 为弧头,此时的图称为有向图. G1 = (V1, A1)          V1 = {v1, v2, v3, v4} A1 =