数据结构—图的总结

本文详细介绍了图的定义、存储结构(邻接矩阵和邻接表)、图的遍历(深度优先与广度优先)、最小生成树(Prim和Kruskal算法)以及最短路径(Dijkstra和Floyd算法),并通过实例展示了如何在通信网络设计中应用这些理论。
摘要由CSDN通过智能技术生成

1.导言

2.思维导图

图的总结

3.图的定义

  • 顶点ii的出度:第ii行1的个数。顶点ii的入度,第ii列1的个数。
    图由顶点集V(G)和边集E(G)组成,记为G=(V,E)。其中E(G)是边的有限集合,边是顶点的无序对(无向图)或有序对(有向图)。
  • 对有向图来说,E(G)是有向边(也称弧(Arc))的有限集合,弧是顶点的有序对,v、w是顶点, v为弧尾(箭头根部),w为弧头(箭头处)。
  • 对无向图来说,E(G)是边的有限集合,边是顶点的无序对,记为(v, w)或者(w, v),并且(v, w)=(w,v)。
  • 顶点的度、入度、出度
    顶点v的度:与v相关联的边的数目;
    顶点v的出度:以v为起点有向边数;
    顶点v的入度:以v为终点有向边数。
  • 路径与回路
    简单路径:序列中顶点不重复出现的路径
    简单回路:序列中第一个顶点和最后一个顶点相同的路径
  • 连通图(强连通图):在无(有)向图中,若对任何两个顶点v、u都存在从v到u的路径,则称图G为连通图(强联通图)。
  • 极大连通子图:该子图是G连通子图,将G的任何不在该子图的顶点加入,子图将不再连通。
    极小连通子图:该子图是G的连通子图,在该子图中删除任何一条边,子图都将不再连通。

4.图的存储结构

邻接矩阵

  • 概念:用一个一维数组存放图中所有顶点数据;用一个二维数组存放顶点间关系(边或弧)的数据,这个二维数组称为邻接矩阵。用邻接矩阵表示图,很容易确定图中任意两个顶点是否有边相连。邻接矩阵分为有向图邻接矩阵和无向图邻接矩阵。对无向图(无向简单图)而言,邻接矩阵一定是对称的,而且对角线一定为零,有向图则不一定如此。
  • 邻接矩阵结构体定义
#define MAXV 最大顶点个数
//声明顶点类型
typedef struct {
   
	int number;/*顶点编号*/
	Info Type info;/*顶点其他信息*/
}VertexType;
//声明邻接矩阵类型
typedef struct {
   
	int edges[MAXV][MAXV];/*邻接矩阵*/
	int n, e;/*顶点数、边数*/
	VertexType vexs[MAXV];/*顶点信息*/
}MatGraph;
  • (1)无向图:
    在这里插入图片描述
  • (2)有向图:
    在这里插入图片描述
  • 建图
void CreateMGraph(MGraph& g, int n, int e)//邻接矩阵建图 
{
    //n顶点个数,e边个数
    int i, j;
    int a, b;
    for (i = 1; i <= n; i++)   //注意输入的起始顶点值从0还是1开始
        for (j = 1; j <= n; j++)
            g.edges[i][j] = 0;
    for (i = 0; i < e; i++)
    {
   
        cin >> a >> b;
        g.edges[a][b] = 1;
        g.edges[b][a] = 1;
    }
    g.n = n;
    g.e = e;
}

邻接表

  • 概念:邻接表是数组和链表的结合。对于每个顶点都建立一个单链表存储该顶点所有的邻接点。然后将定义一个结构体VNode,里面保存顶点邻接点的链表和顶点其他信息。设置VNode类型的结构体数组AdjGraph[]就可以保存图中所有顶点的邻接点,达到保存图中所有边的目的。结构体数组AdjGraph[]即为邻接表。
  • 邻接表的结构体定义
typedef struct ANode //边结点;
{
   
   int adjvex;//指向该边的终点编号;
   struct ANode*nextarc;//指向下一个邻接点;
   INfoType info;//保存该边的权值等信息;
}ArcNode;
typedef struct  //头结点
{
   
   int data;//顶点;
   ArcNode *firstarc;//指向第一个邻接点;
}VNode;
typedef struct
{
   
   VNode adjlist[MAX];//邻接表;
   int n,e;//图中顶点数n和边数e;
}AdjGraph;

  • (1)无向图:
    在这里插入图片描述

  • (2)有向图:
    在这里插入图片描述

  • 邻接矩阵和邻接表表示图的区别

    • 思路:
      1、在邻接矩阵表示中,无向图的邻接矩阵是对称的。邻接矩阵需要申请一个二维数组,空间复杂度为O(n2)
      2、在邻接表的表示中,无向图的同一条边在邻接表中存储的两次。因为共有e条边和n个结点,需要开辟n个空间来保存结点,e个空间来保存e条边信息,所以,创建邻接表的空间复杂度为O(n+e)

5.图的遍历

深度优先遍历

  • 概念:
    1、首先以一个未被访问过的顶点作为起始顶点,沿当前顶点的边走到未访问过的顶点;
    2、当没有未访问过的顶点时,则回到上一个顶点,继续试探别的顶点,直至所有的顶点都被访问过。
  • 代码
int visited[MaxN]={
   0}; //记录顶点的访问状态
int result[MaxN]; //result数组记录DFS遍历结果
int N,E,k;// N为顶点数,E为边数,k记录遍历结果下标

void DFS(int v){
   
	visited[v]=1;
	result[k++]=v;
	for (int i=0;i<N;i++){
   
		if (G[v][i]==1 && visited[i]==0)
			DFS(i);
	}
}

int main(){
   
	for (int i=0;i<N;i++){
   
		k = 0;
		if (visited[i]==0){
   
			DFS(i);
                 //用{}打印出一个连通分量
			cout<<"{ ";
			for (int j=0;j<k;j++)
				cout<<result[j]<<' ';
			cout<<"}"<<endl;
		}

	}
return 0;
}

广度优先遍历

  • 思路:有点类似于树的层序遍历,也就是像剥洋葱一样,“一层一层地剥开”。即从一个选定的点出发,将与其直接相连的点都收入囊中,然后依次对这些点去收与其直接相连的点。重复到所有点都被访问然后结束。
  • 代码
int visited[MaxN]={
   0}; //记录顶点的访问状态
int result[MaxN]; //result数组记录BFS遍历结果
int N,E,k;// N为顶点数,E为边数,k记录遍历结果下标

void BFS(int v){
   
	queue<int> q;
	q.push(v);
	visited[v]=1;
	result[k++]=v;
	while
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值