IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 图的存储结构 -> 正文阅读

[数据结构与算法]图的存储结构

图的存储结构

1.邻接矩阵表示法

邻接矩阵可以表示顶点之间的关系,可以借助二维数组表示,对于无向图若两点之间的边存在,则该位置的值为1,反之则为0;对于有向图还需要考虑入点和出点的问题,若一条边从 i 点出发进入 j 点,则 a [ i ][ j ]=1,而 a [ j ][ i ]仍为0。

采用邻接矩阵表示法创建图时,用一个二维数组储存边,再用一个一维数组储存点的名称和边的权值即可。下面以创建无向网为例

#include <iostream>
#include <string>
using namespace std;
//无向网的创建 
#define maxint 32767
#define mvnum 100 
typedef struct
{
	char vexs[mvnum];
	int arcs[mvnum][mvnum];
	int vexnum,arcnum;//图的总顶点数,总边数 
}AMGraph;
int Locate(char a,char b[]);
int CreateUDN(AMGraph &G)
{
	char a,b;
	int w;
	int j,k;
	//cout<<"请输入图的总顶点数和总边数"<<endl; 
	cin>>G.vexnum>>G.arcnum; 
	//cout<<"请输入图的顶点信息"<<endl; 
	for(int i=0;i<G.vexnum;i++)
	cin>>G.vexs[i];//读入点的信息
	 for(int i=0;i<G.vexnum;i++)
	 {
	 	for(int j=0;j<G.vexnum;j++)
	 	{
	 		G.arcs[i][j]=maxint;//初始化图使所有边均不存在(值为无穷大) 
		 }
	 }
	 for(int i=0;i<G.arcnum;i++)
	 {
	 	//cout<<"请输入一条边链接的两个顶点和该边权值"<<endl; 
	 	cin>>a>>b>>w;
	 	j=Locate(a,G.vexs),k=Locate(b,G.vexs);
	 	G.arcs[j][k]=w;	 
		G.arcs[k][j]=w;	
	}
	return 1;
}
int Locate(char a,char b[])
{
	for(int i=0;i<mvnum;i++)
	{
		if(b[i]==a)
		return i;
	}
}
int main()
{
	AMGraph G;
	CreateUDN(G);
	for(int i=0;i<G.vexnum;i++)
	{
		for(int j=0;j<G.vexnum;j++)
		{
			cout<<G.arcs[i][j]<<' ';
		}
		cout<<endl;
	}
	return 0;
}

2.邻接表表示法

图中每个顶点对应一个结点,所有顶点用一个一维数组或一个单链表存储,每个顶点的邻接点构成一个线性表,利用单链表来存储。

邻接表在建立时若顶点单链表中储存的是顶点指向的点则该表为正邻接表,便于计算顶点的出度;

若储存的是指向顶点的点则该表为逆邻接表,便于计算顶点的入度。

对于带权的网图,在顶点中加入数据域即可。

#include <iostream>
#include <string>
using namespace std;
//无向网的创建(邻接表法) 
#define mvnum 100 
typedef struct Arcnode
{
	int weight;//边的权值 
	struct Arcnode *next;//指向链表中下一个结点(下一条边)
	int p;//该边邻接的点 
}Arcnode;//边结点 
typedef struct
{
	char name;//顶点名 
	Arcnode *firtstarc;//指向邻接的第一条边 
}Adjlist[mvnum];//存放顶点的一维数组 
typedef struct
{
	Adjlist vertices;//创建存放顶点的一维数组 
	int vexnum,arcnum;//图的总顶点数,总边数 
}ALGraph;

int Locate(char a,ALGraph G)
{
	for(int i=0;i<mvnum;i++)
	{
		if(G.vertices[i].name==a)
		return i;
	}
}

int CreateUDN(ALGraph &G)
{
	char a,b;
	int w;
	int j,k;
	cout<<"请输入图的总顶点数和总边数"<<endl; 
	cin>>G.vexnum>>G.arcnum; 
	cout<<"请输入图的顶点信息"<<endl; 
	for(int i=0;i<G.vexnum;i++)
	{
		cin>>G.vertices[i].name;//读入点的信息
		G.vertices[i].firtstarc=NULL;//表头指针赋空值 
	}
	 for(int i=0;i<G.arcnum;i++)
	 {
	 	cout<<"请输入一条边链接的两个顶点和该边权值"<<endl; 
	 	cin>>a>>b>>w;
	 	j=Locate(a,G),k=Locate(b,G);
	 	Arcnode *p1;
	 	p1=new Arcnode;
	 	p1->p=j;
	 	p1->weight=w;
	 	p1->next=G.vertices[j].firtstarc;
	 	G.vertices[j].firtstarc=p1;//将数据插入链表
		Arcnode *p2;
	 	p2=new Arcnode;
	 	p2->p=k;
	 	p2->weight=w;
	 	p2->next=G.vertices[k].firtstarc;
	 	G.vertices[k].firtstarc=p2;//将数据插入链表
	}
	return 1;
}
int main()
{
	ALGraph G;
	CreateUDN(G);
	Arcnode *p3;
	p3=G.vertices[0].firtstarc;
	while(p3!=NULL)
	{
		cout<<p3->p<<' '<<p3->weight<<endl;
		p3=p3->next;
	}
	return 0;
}

邻接表法的缺点在于不便于判断两点之间是否有边,以及某点的入度和出度难以同时判断,下面的十字链表较好的解决了这一问题。

3.十字链表法

构造有向图时可以对邻接表法进行优化,使可以同时得到某点的入度和出度,这就是十字链表法,也可以看做是邻接表和逆邻接表的结合。不同的地方在于

#define mvnum 100 
typedef struct Arcnode
{
	int weight;//边的权值 
	struct Arcnode *hlink,*tlink;//生成两个链表
	int tailvex,headvex;//该边邻接的两个点 
}Arcnode;//对于边结点,记录该边邻接的两个点和链表中弧头相同的下一条弧和弧尾相同的下一条弧
typedef struct
{
	char name;//顶点名
	Arcnode *firstin,*firstout;//指向该点的第一条入弧和第一条出弧 
}Adjlist[mvnum];//存放顶点的一维数组 
typedef struct
{
	Adjlist vertices;//创建存放顶点的一维数组 
	int vexnum,arcnum;//图的总顶点数,总边数 
}ALGraph;

十字链表的时间复杂度与邻接表的相同,在有向图中十字链表的应用更加广泛

4.邻接多重表

邻接多重表的结构与十字链表类似,便于找到同一条边的两个结点,即结点依附于边存在,实现的代码如下

#define mvnum 100 
typedef struct Arcnode
{
	int weight;//边的权值 
	int mark;//访问标记 
	struct Arcnode *ilink,*jlink;//指向依附于这两个顶点的下一条边 
	int ivex,jvex;//该边依附的两个顶点位置 
}Arcnode;//边结点 
typedef struct
{
	char name;//顶点名 
	Arcnode *firtstarc;//指向第一条依附于该顶点的边 
}Adjlist[mvnum];//存放顶点的一维数组 
typedef struct
{
	Adjlist vertices;//创建存放顶点的一维数组 
	int vexnum,arcnum;//图的总顶点数,总边数 
}ALGraph;

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-17 01:30:19  更:2021-08-17 01:30:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 17:25:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计