第六章 图

本章的主要内容是:
图的逻辑结构
图的存储结构及实现
图的连通性
最小生成树
最短路径
AOV网与拓扑排序
AOE网与关键路径

6.1 图的逻辑结构
1.图是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:
G=(V,E) (Graph Vertex Edge)
其中:G表示一个图,V是图G中顶点的集合,E是图G中顶点之间边的集合。
在线性表中,元素个数可以为零,称为空表;
在树中,结点个数可以为零,称为空树;
在图中,顶点个数不能为零,但可以没有边。
2.图的基本术语
简单图:在图中,若不存在顶点到其自身的边,且同一条边不重复出现。
简单图:在图中,若不存在顶点到其自身的边,且同一条边不重复出现。
3.邻接、依附
无向图中,对于任意两个顶点vi和顶点vj,若存在边(vi,vj),则称顶点vi和顶点vj互为邻接点,同时称边(vi,vj)依附于顶点vi和顶点vj。
4.无向完全图:在无向图中,如果任意两个顶点之间都存在边,则称该图为无向完全图。
有向完全图:在有向图中,如果任意两个顶点之间都存在方向相反的两条弧,则称该图为有向完全图。
5.稀疏图:称边数很少的图为稀疏图;
稠密图:称边数很多的图为稠密图。
顶点的度:在无向图中,顶点v的度是指依附于该顶点的边数,通常记为TD (v)。
顶点的入度:在有向图中,顶点v的入度是指以该顶点为弧头的弧的数目,记为ID (v);
顶点的出度:在有向图中,顶点v的出度是指以该顶点为弧尾的弧的数目,记为OD (v)。
6.权:是指对边赋予的有意义的数值量。
网:边上带权的图,也称网图。
7.路径:在无向图G=(V, E)中,从顶点vp到顶点vq之间的路径是一个顶点序列(vp=vi0,vi1,vi2, …, vim=vq),其中,(vij-1,vij)∈E(1≤j≤m)。若G是有向图,则路径也是有方向的,顶点序列满足<vij-1,vij>∈E。
8.回路(环):第一个顶点和最后一个顶点相同的路径。
简单路径:序列中顶点不重复出现的路径。
简单回路(简单环):除了第一个顶点和最后一个顶点外,其余顶点不重复出现的回路。
9.连通图:在无向图中,如果从一个顶点vi到另一个顶点vj(i≠j)有路径,则称顶点vi和vj是连通的。如果图中任意两个顶点都是连通的,则称该图是连通图。连通分量:非连通图的极大连通子图称为连通分量。
10.强连通图:在有向图中,对图中任意一对顶点vi和vj(i≠j),若从顶点vi到顶点vj和从顶点vj到顶点vi均有路径,则称该有向图 是强连通图。强连通分量:非强连通图的极大强连通子图。
11.生成树:n个顶点的连通图G的生成树是包含G中全部顶点的一个极小连通子图。
12.生成森林:在非连通图中,由每个连通分量都可以得到一棵生成树,这些连通分量的生成树就组成了一个非连通图的生成森林。
6.2 图的存储结构及实现
1 深度优先遍历
广度优先遍历
2.
邻接矩阵存储无向图的类
const intMaxSize=10;
template
class MGraph// Adjacency Matrix
{
public:
MGraph(Ta[ ], intn, inte );
~MGraph( )
void DFSTraverse(intv);
void BFSTraverse(intv);
private:
T vertex[MaxSize];
intarc[MaxSize][MaxSize];
intvertexNum,arcNum;}
邻接矩阵中图的基本操作——构造函数
template
MGraph::MGraph(Ta[ ], intn, inte)
{
vertexNum=n; arcNum=e;
for (i=0; i<vertexNum; i++)
vertex[i]=a[i];
for (i=0; i<vertexNum; i++) //初始化邻接矩阵
for (j=0; j<vertexNum; j++)
arc[i][j]=0;
for (k=0; k<arcNum; k++) //依次输入每一条边
{
cin>>i>>j; //边依附的两个顶点的序号
arc[i][j]=1; arc[j][i]=1; //置有边标志}}
邻接矩阵中图的基本操作——深度优先遍历
template
void MGraph::DFSTraverse(intv)
{
cout<<vertex[v]; visited [v]=1;
for (j=0; j<vertexNum; j++)
if (arc[v][j]==1 && visited[j]==0)
DFSTraverse(j );}
邻接矩阵中图的基本操作——广度优先遍历
template void MGraph::BFSTraverse(intv){ front=rear=-1; //假设采用顺序队列且不会发生溢出cout<<vertex[v]; visited[v]=1; Q[++rear]=v; while (front!=rear){v=Q[++front]; for (j=0; j<vertexNum; j++)if (arc[v][j]==1 && visited[j]==0 ){cout<<vertex[j]; visited[j]=1; Q[++rear]=j;}}
3.定义邻接表的结点
structArcNode
{ intadjvex;
ArcNodenext;
};
template
structVertexNode
{
T vertex;
ArcNode
firstedge;
};
邻接表存储有向图的类
const intMaxSize=10; //图的最大顶点数
template
class ALGraph// Adjacency List
{
public:
ALGraph(Ta[ ], intn, inte);
~ALGraph;
void DFSTraverse(intv);
void BFSTraverse(intv);
private:
VertexNodeadjlist[MaxSize];
intvertexNum, arcNum;
};
邻接表中图的基本操作——构造函数
template
ALGraph::ALGraph(Ta[ ], intn, inte)
{
vertexNum=n; arcNum=e;
for (i=0; i<vertexNum; i++)
//输入顶点信息,初始化边表
{
adjlist[i].vertex=a[i];
adjlist[i].firstedge=NULL;}
邻接表中图的基本操作——深度优先遍历
template
void ALGraph::DFSTraverse(intv)
{
cout<<adjlist[v].vertex; visited[v]=1;
p=adjlist[v].firstedge;
while (p!=NULL)
{
j=p->adjvex;
if (visited[j]==0)DFSTraverse(j);
p=p->next;}}
邻接表中图的基本操作——广度优先遍历
void ALGraph::BFSTraverse(intv)
{
front=rear=-1;
cout<<adjlist[v].vertex; visited[v]=1; Q[++rear]=v;
while (front!=rear)
{
v=Q[++front]; p=adjlist[v].firstedge;
while (p!=NULL)
{
j= p->adjvex;
if (visited[j]==0){
cout<<adjlist[j].vertex; visited[j]=1; Q[++rear]=j;
}
p=p->next;}}}

4.MST性质
假设G=(V, E)是一个无向连通网,U是顶点集V的一个非空子集。若(u, v)是一条具有最小权值的边,其中u∈U,v∈V-U,则必存在一棵包含边(u, v)的最小生成树。

普里姆(Prim)算法
基本思想:设G=(V, E)是具有n个顶点的连通网,T=(U, TE)是G的最小生成树,T的初始状态为U={u0}(u0∈V),TE={ },重复执行下述操作:在所有u∈U,v∈V-U的边中找一条代价最小的边(u, v)并入集合TE,同时v并入U,直至U=V。

克鲁斯卡尔(Kruskal)算法
基本思想:设无向连通网为G=(V, E),令G的最小生成树为T=(U, TE),其初态为U=V,TE={ },图G中每个顶点自成一个连通分量。按照边的权值由小到大的顺序,在G的边集E中选择代价最小的边,
•若该边依附的顶点属于T中不同的连通分量上,则将此边作为最小生成树的边加入到T中,
•否则舍去此边而选择下一条代价最小的边。
•依此类推,直至所有顶点都在同一连通分量上。
此连通分量便为G的一棵最小生成树。
5.Dijkstra算法
基本思想:设置一个集合S存放已经找到最短路径的顶点,S的初始状态只包含源点v。
•初使时令S={v},T={其余顶点},T中顶点对应的距离值:
?若存在< v, vi >,为< v, vi >弧上的权值
?若不存在< v, vi>,为∝
•从T中选取一个其距离值为最小的顶点vk,加入S
•对T中顶点的距离值进行修改:若加进vk作中间顶点,从v到vi的距离值比不加vk的路径要短,则修改此距离值
•重复上述步骤,直到S中包含所有顶点,即S=V为止。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值