图的相关种类

目录

 

数据类型

存储结构

邻接矩阵表示法

无向图

邻接矩阵表示

有向图

实现

邻接矩阵表示

存储结构

创建无向图

优点

缺点

邻接表法表示

表示无向图

表示有向图

存储结构

无向网

特点

十字链表与多重表

十字链表

存储结构

多重表

存储结构


 

数据类型

4c10f57618e04bb6adbafacd03956185.png

存储结构

062b0cdb90bc4b7e8909c64bce5fce73.png

邻接矩阵表示法

无向图

82076c989973451198b136c319300c1f.png

 

a77a98128d264bbfa2bb2b831e1abda9.png

无向图的度=矩阵中非0元素个数和

无向图的边=非0元素个数的一半(因为每条边被重复存储一次)

邻接矩阵表示

有向图

e6701a86f644499aa5d4657a304da27c.png

626d8141cde64b0c84c43d698f543156.png

有向图的度=出度+入度=每一行元素和+每一列元素和=矩阵中非0元素个数和*2

有向图的弧=非0元素个数和=入度数=出度数

5cfeac84cd2b45f791caacd7d787e574.png

实现

邻接矩阵表示

存储结构

fe9d6c51522f45b0b9f47b452957b2ff.png

创建无向图

64f4519378064580b6640e1a1a1b575f.png

 

84ebc3a8932d49c89d9f3f165a47de4c.png

8d8d9151efb247a2a912144c3b25ca57.png

c15fbe05970746efb4aac1c4e73093fc.png

优点

81f7749a914d4d5d89ce10f40ca7310f.png

缺点

5ddd0454440b405eba9720ac6ffa5b40.png

邻接表法表示

37d138850ac64cc18a7f1766fc0bb87f.png

表示无向图

9a055956ad41476489c175349e20a3b9.png

表示有向图

67e1e9aa1681431e99056bd47931b2fb.png

示例

c6950f5e6bdb47ae85d9501e3e27e0ad.png

存储结构

b62c6f0284f34cb38cae9d41ccedfb0d.png

 

43db3371d3544d56a360dba19b127e70.png

 

60a153937dc945d3bddcc3ec15851302.png

5f0e731e47d84e1ea6f1a82a41dcb444.png

先表示出所有边结点,再将边结点组成链表连接到各个对应顶点上。

示例

28bd28a766df487cb3dabe8f5e2d98ae.png

无向网

dc1afdc2a52a4423b957babc7dea9c52.png

2cc4a1f5bb1f419eb81b8d3e4be65d55.png

26bb2367ecc042bf96a8d7faf08c66e3.png

特点

b01c02d12157472097842c4097a7a086.png

404e3781891d43d79f79693653b8d583.png

十字链表与多重表

d0b46919203e4fdc8f0969eefd966103.png

十字链表

为解决有向图求度不方便的问题

952dba7395aa4137a572be56ed4d926d.png

存储结构

firstin表示以data为弧头(终点,即指向data顶点-入)的边,firstout表示以data为弧尾(起点-出)的边。

tailvex表示弧的弧尾(起点)顶点序号,headvex表示弧的弧头(终点)顶点序号,

hlink指向下一个弧头相同的弧,tlink指向下一个弧尾相同的弧。

df69c97674f44a02b067f9390479edfe.png

先列出所有弧,再连接到顶点。

多重表

068238c1f6d0460e92bb54b77c72a73f.png

存储结构

7b466afcfdf54c96b9b88bc30da3800f.png

相关代码

#include <iostream>
using namespace std;
//图的存储

//1.邻接矩阵存储:边数+顶点数+顶点表-一维+边表-二维
#define maxn 20
#define infi 33333333 
//类型定义 
typedef struct {
	char vexs[maxn];//顶点表 
	int arc[maxn][maxn];//边表 
	int vexnum,arcnum;//顶点数与边数 
}adjgraph;
//创建无向图
//1.输入边数与顶点数,初始边表-无穷 
//2.输入顶点,为顶点表赋值 
//3.输入边的顶点及权值,为边表赋值:需要先确定顶点的下标才能确定边 
int getvex(adjgraph *g,char v){
	for(int i=1;i<=g->vexnum;i++)
		if(g->vexs[i]==v) return i;
	return 0;
}
//后期实现!!!! 
//void print(adjgraph *g){
//	for(int i=1;i<=g->vexnum;i++)
//		if(g->vexs[i]==v) return i;
//} 
void create(adjgraph *g){
	char vex1,vex2;//存储边的顶点 
	int weigh;//存储边的权值 
	int  v1,v2;//存储边的下标 
	cout<<"输入顶点数及边数:"<<endl;
	cin>>g->vexnum>>g->arcnum;
	for(int i=1;i<=g->vexnum;i++){//初始边表 
		for(int j=1;j<=g->arcnum;j++){
			g->arc[i][j]=infi;
    	} 
	}
    for(int i=1;i<=g->vexnum;i++){//存储顶点信息 
    	cout<<"请输入第"<<i<<"个顶点信息:\n";
    	cin>>g->vexs[i];
    }
    for(int j=1;j<=g->arcnum;j++){//存储边表信息 
    	cout<<"请输入第"<<j<<"条边的顶点信息:\n";
    	cin>>vex1>>vex2;
    	cout<<"请输入第"<<j<<"条边的权值:\n";
    	cin>>weigh;
    	v1=getvex(g,vex1);
    	v2=getvex(g,vex2);
    	g->arc[v1][v2]=weigh;//单向
		g->arc[v2][v1]=weigh;//双向-无向图 
	}
}

//2.邻接表表示:顶点表+顶点数+边数 
//顶点表:顶点信息+第一条边结点
//边结点:顶点编号+边权+下一条边
int getvex2(adjlist &g,char v){
	for(int i=1;i<=g.vnum;i++)
		if(g.vex[i].vex==v) return i;
	return 0;
}
typedef struct acrnode{//边结点 
	int adjacr;//记录邻接顶点编号-弧尾 
	int weigh;//权值 
	acrnode *next;//有相同弧头顶点的下一个边结点 
}acrnode; 
typedef struct vnode{//顶点类型 
	char vex;
	acrnode *first;
}vnode; 
typedef struct {//邻接表 
	int vnum,acrnum;
	vnode vex[maxn];//顶点表 
}adjlist;
void create(adjlist &g){
	char v1,v2;
	int  vex1,vex2;
	acrnode n,m; 
	//1.输入顶点数、边数
	cin>>g.vnum>>g.acrnum; 
	//2.初始邻接表:输入顶点,初始顶点表头指针为空
	for(int i=1;i<=g.vnum;i++){
		cin>>g.vex[i].vex;
		g.vex[i].first=NULL;
	}
	//3.输入边顶点,构造边结点,记录弧头与弧尾顶点,头插边表
	for(int i=1;i<=g.acrnum;i++){
		cin>>v1>>v2;
		vex1=getvex2(g,v1);//弧尾 
		vex2=getvex2(g,v2);//弧头
		n=new acrnode;//构造边结点
		//记录边v1->v2; 并插入到顶点v1的边表中 
		n->adjacr=vex2;//存储邻接v1的顶点v2的编号 
		n->next=g.vex[vex1].first;//下一个边结点存储原来v1顶点的第一个边结点
		g.vex[vex1].first=n;//更新v1顶点的第一条边为n,实现插入 
		//记录边v2->v1:新边结点结构-左边记录邻接指点编号  权值   右边记录具有同样以v2为弧尾的下一条边结点 
		m=new acrnode;
		m->adjacr=vex1;//记录邻接v2的顶点v1的编号
		m->next=g.vex[vex2].first;//下一个边结点存储v2指向的第一个边结点 
		g.vex[vex2].first=m;//更新顶点v2的第一条边结点,实现插入 
	} 
}

//3.十字链表表示:弧结点+顶点结点==>顶点表+弧数+顶点数-解决有向图找出入度的问题
//弧结点 
typedef struct acrnode{
	int tailvex,headvex;//弧头+弧尾编号
	struct acrnode *tailacr,*headacr;//分别具有相同弧头和弧尾的下一条弧结点 
}arcnode;
typedef struct vexnode{
	char data;//顶点信息 
	acrnode *tail,*head;//以顶点为弧尾或为弧头的弧结点 
}vexnode; 
typedef struct node{
	int vnum,acrnum;
	vexnode v[maxn];
};

//4.多重表:顶点结点+边结点==>顶点表+边数+顶点数-解决无向图重复存边的问题
typedef struct acrnode{
	int tailvex,headvex;//组成边结点的两顶点编号 
	struct acrnode *tailacr,*headacr;//与边结点顶点相同的边结点 
	int weigh;//边的权重 
}; 
//顶点结点:顶点信息+指向第一条边的指针 
typedef struct vexnode{
	char data;
	acrnode *first;//第一条边结点 
}; 
typedef struct node{
	int vnum,vacr;
	vexnode v[maxn];//顶点表 
}; 
int main(){
	adjgraph g;
	create(&g);
	return 0;
} 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值