图的定义
- 图表示的是一种多对多的关系,线性表和树也能看成是一种特殊的图
- 图一定有一组非空的顶点,我们用V来表示顶点 (非空)
- 图一定包含一组边, 我们用E来表示 (不是非空的)
- 如果连接两个顶点的边是无向边 则用(V,W) 来表示 VW都是顶点
- 如果连接两个顶点的边是有向边 则用<V,W>来表示 代表一条由V通向W的有向边
- 图不存在重边和自回路 自回路(<V,V>)不存在
- 图由一组非空的有限顶集和一组有限边集组成
- 权重: 一条边上的值 有的图上的边有权重 有的图上的边没有权重
- 图的四种情况: 无向无权重图 无向有权重图 有向无权重图 有向有权重图
- 如果图里的边有权重 可以叫这张图叫做网络
- 邻接点: 于a顶点有直接的边相连的点 叫做 a顶点的邻接点
- 图的度: 分为出度 和 入度 无向图的度 = 出度或者入度 出度和入度相同 /有向图的度 = 出度 + 入度
- 出度: 由a节点出发的边的数量 就是a节点的出度
- 入度: 指向a节点的边就是a节点的入度
邻接矩阵实现图:
邻接矩阵表示一张图:
创建一个二维数组: int G[N][N] 可以用来表示 从编号0 - (n-1)个顶点的图
数组里 G[0][1] 里存放的值为 无权图就是0/1 表示第0个节点和第一个几点是否有边相连
有权图里面可以存放边的权值
二维数组里的第i行 一整行存储的是第i个节点的入度 第i列 整列存储的是第i个节点的出度
邻接矩阵的特点
- 一张邻接矩阵的对角线 全部为0 也就是没有边 因为图没有自回路 所以G[1][1]是不会有边的
- 对于无向图来说沿着对角线折叠上半部分和下半部分是一样的 一条边会被存储两次浪费空间
好处和坏处
- 方便检查两个顶点之间是否有边
- 方便找到任一节点的所有邻接点
- 方便计算节点的出度和入度
- 但是对于稀疏图(有多个节点但是只有很少的边)来说浪费时间空间 里面存储了大量无意义的0
- 对稠密图还是很实惠的
结构和代码:
边的结构
public
邻接矩阵的结构
public
初始话一张只有N个节点但是没有边的图
/**
给无向无权的图插入一条边: 因为无向所以两个顶点之间都需要设1
/**
给无向有权的图插入一个边
/**
给有向无权的图插入一个边
/**
给有向有权的图插入一个边
/**
传入一个边的数组根据这个数组构建一种图
- 根据边的数量构建一种空图
- 循环读取边的值 并且根据图的类型进行插入边
/**
删除一条边
/**
计算一个节点的入度 和出度(矩阵的行和列)
/**
图的深度优先遍历 有向无向图都是一个遍历法
- 从给定的入口顶点开始遍历 读取入口的值
- 循环遍历读取入口的所有邻接点 这里的邻接点我们使用入度的 出度不用
- 这里的思想使用的是入栈和出栈的
/**
图的广度优先遍历
- 从给定的起点开始 读取起点的值
- 将起点入队
- 如果队列里不空则一直循环下面的操作
- 将那个元素的所有邻接点(入度的)入队 并读取邻接点的值
/**