图的存储遍历及最小生成树Word格式.docx
《图的存储遍历及最小生成树Word格式.docx》由会员分享,可在线阅读,更多相关《图的存储遍历及最小生成树Word格式.docx(14页珍藏版)》请在冰豆网上搜索。
代表两条不同的弧。
【例】<
vi,vj>
表示一条有向边,vi是边的始点(起点),vj是边的终点。
注意:
<
和<
vj,vi>
是两条不同的有向边。
(2)有向图的表示
【例】上面7.1图中G2是一个有向图。
图中边的方向是用从始点指向终点的箭头表示的,该图的顶点集和边集分别为:
顶点集V={v1,v2,v3}
弧集E={<
v1,v2>
<
v1,v3>
v2,v3>
v3,v2>
}。
<
与<
表示两条不同的边。
2.无向图
如图7.1G1中所示的每条边都是没有方向的,则称G为无向图(Undigraph)。
(1)无向边的表示
通常用圆括号表示无向边,(v,w)表示顶点v和w间相连的边。
在无向图中(v,w)和(w,v)表示同一条边,如果顶点v,w之间有边(v,w),则v,w互称为邻接点。
【例】无序对(vi,vj)和(vj,vi)表示同一条边。
(2)无向图的表示
【例】上面7.1图中的G1是无向图,它们的顶点集和边集分别为:
顶点集:
V={v1,v2,v3,v4}
边集:
E={(v1,v2),(v1,v3),(v1,v4),(v2,v3),(v3,v4)}
(v2,v1)与(v1,v2)表示同一条边,(v2,v3)与(v3,v2)也表示同一条边,等等。
3.图G的顶点数n和边数e的关系
(1)若G是无向图,则0≤e≤n(n-1)/2
恰有n(n-1)/2条边的无向图称无向完全图(Undireet-edCompleteGraph)
(2)若G是有向图,则0≤e≤n(n-1)。
恰有n(n-1)条边的有向图称为有向完全图(DirectedCompleteGraph)。
注意:
完全图具有最多的边数。
任意一对顶点间均有边相连。
4.对图的讨论中我们对图作一些限制:
第一,图中不能有从顶点自身到自身的边(即自身环),就是说不应有形如(vx,vx)的边或<
vx,vx>
的弧。
第二,两个顶点vt和vu之相关联的边不能多于一条。
图的邻接矩阵
1.图的邻接矩阵表示法
在图的邻接矩阵表示法中:
①用邻接矩阵表示顶点间的相邻关系
②用一个顺序表来存储顶点信息
2.图的邻接矩阵(AdacencyMatrix)
设G=(V,E)是具有n个顶点的图,则G的邻接矩阵是具有如下性质的n阶方阵:
【例】下图中无向图G5和有向图G6的邻接矩阵分别为Al和A2。
从图的邻接矩阵表示法中可以得到如下结论:
(1)对于n个顶点的无向图,有A(i,i)=0,1≤i≤n。
(2)无向图的邻接矩阵是对称的,即A(i,j)=A(j,i),1≤i≤n,1≤j≤n。
(3)有向图的邻接矩阵不一定对称的。
因此用邻接矩阵来表示一个具有n个顶点的有向图时需要n2个单位来存储邻接矩阵;
对有n个顶点的无向图则需存入上(下)三角形,故只需n(n+1)/2个单位。
(4)无向图的邻接矩阵的第i行(或第i列)非零元素的个数正好是第i个顶点的度TD(vi)。
(5)有向图的邻接矩阵的第i行(或第i列)非零元素的个数正好是第i个顶点的出度OD(vi)[或入度ID(vi)]。
3.网(带权值的图)的邻接矩阵
若G是网络,则邻接矩阵可定义为:
wij表示边上的权值;
∞表示一个计算机允许的、大于所有边上权值的数。
【例】下面(a)是一个带权图,(b)是对应的邻接矩阵的存储结构
(a)带权图
(b)邻接矩阵
4.邻接矩阵的图类
constintMaxVertices=10;
constintMaxWeight=32767;
classAdjMWGraph
{private:
intVertices[10];
//顶点信息的数组
intEdge[MaxVertices][MaxVertices];
//边的权值信息的矩阵
intnumE;
//当前的边数
intnumV;
//当前的顶点数
public:
………;
//公有函数
private:
//私有函数
}
①在简单应用中,可直接用二维数组作为图的邻接矩阵(顶点表及顶点数等均可省略)。
②当邻接矩阵中的元素仅表示相应的边是否存在时,EdgeTyPe可定义为值为0和1的枚举类型。
③无向图的邻接矩阵是对称矩阵,对规模特大的邻接矩阵可压缩存储。
④邻接矩阵表示法的空间复杂度S(n)=0(n2)。
图的邻接链表
邻接链表(AdjacencyList)是图的一种链式存储结构,与树型结构中的孩子链表相似。
通常邻接链表也称邻接表。
1.邻接表的结点结构
边结点结构
邻接表中每个表结点均有两个域:
①邻接点域adjvex
存放与vi相邻接的顶点vj的序号j。
②链域next
将邻接表的所有表结点链在一起。
如果带权图,则在表结点中还应增加一个保存权值等相关信息info。
2.邻接表的表示
对于无向图,vi的邻接表中每个表结点都对应于与vi相关联的一条边。
因此,将邻接表的表头向量称为顶点表。
将无向图的邻接表称为边表。
n个顶点e条边的无向图的邻接表表示中有n个顶点表结点和2e个边表结点。
对于有向图,vi的邻接表中每个表结点都对应于以vi为始点射出的一条边。
因此,将有向图的邻接表称为出边表。
n个顶点e条边的有向图,它的邻接表表示中有n个顶点表结点和e个边表结点。
4.有向图的逆邻接表
在有向图中,为图中每个顶点vi建立一个入边表的方法称逆邻接表表示法。
入边表中的每个表结点均对应一条以vi为终点(即射入vi)的边。
【例】
n个顶点e条边的有向图,它的接表表示中有n个顶点表结点和e个边表结点。
图的遍历
从图中某一顶点出发,按某种搜索方法访遍其余顶点,且使每一顶点仅被访问一次。
这一过程称为图的遍历。
遍历图的基本搜索方法有两种:
深度优先搜索DFS(DepthFirstSearch)和广度优先搜索BFS(BroadFirstSearch)。
这两种方法都适用于有向图和无向图。
图的遍历算法设计需要考虑3个问题:
(1)图的特点没有首尾之分,所以算法的参考要指定访问的第一个顶点。
(2)对图的遍历路径有可能构成一个回路,从而造成死循环,所以算法设计要考虑遍历路径可能的回路问题。
(3)一个顶点可能和若干个顶点都是想邻顶点,要使一个顶点的所有想邻顶点按照某种次序被访问。
对于连通图,从初始顶点出发一定存在路径和图中的所有其他顶点相连,所以对于连通图从初始顶点出发一定可以遍历该图。
图的深度优先遍历
图的深度优先遍历DFS算法是每次在访问完当前顶点后,首先访问当前顶点的一个未被访问过的邻接顶点,然后去访问这个邻接点的一个未被访问过的邻接点,这样的算法是一个递归算法。
1.连通图的深度优先遍历算法思想。
(1)访问初始顶点v并标记顶点v已访问。
(2)查找顶点v的第一个邻接顶点w。
(3)若顶点v的邻接顶点w存在,则继续执行;
否则回溯到v,再找v的另外一个未访问过的邻接点。
(4)若顶点w尚未被访问,则访问顶点w并标记顶点w为已访问。
(5)继续查找顶点w的下一个邻接顶点wi,如果v取值wi转到步骤(3)。
直到连通图中所有顶点全部访问过为止。
【例】现以图7.9(a)为例说明深度过优先搜索过程。
假定v1是出发点,首先访问v1。
因v1有两个邻接点v2、v3均未被访问过,可以选择v2作为新的出发点,访问v2之后,再找v2的未访问过的邻接点。
同v2邻接的有v1、v4、v5,其中v1已被访问过,而v4、v5尚未被访问过,可以v4选择作为新的出发点。
重复上述搜索过程,继续依次访问v8、v5。
访问v5之后,由于与v5相邻的顶点均已被访问过,搜索退回到v8。
由于v8、v4、v2都是已被访问的邻接点,所以搜索过程连续地从v8退回到v4,再退回到v2,最后退回到v1。
这时选择v1的未被访问过的邻接点v3,继续往下搜索,依次访问v3、v6、v7,从而遍历了图中全部顶点。
在这个过程中得到的顶点的访问序列为:
具体算法演示请点击查看
2.深度优先遍历算法
(1)邻接矩阵的深度优先遍历算法:
【算法7.1】
voidAdjMWGraph:
:
Depth(intv,intvisited[])
{cout<
"
\n顶点"
v+1"
权值:
Vertices[v];
visited[v]=1;
for(intcol=0;
col<
numV;
col++)
{if(Edge[v][col]==0||Edge[v][col]==MaxWeight)continue;
if(!
visited[col])Delpth(col,visited);
}
故用邻接矩阵表示图时,搜索一个顶点的所有邻接点需花费O(n)时间,则从n个顶点出发搜索的时间应为O(n2),即DFS算法的时间复杂度是(n2)。
(2)邻接链表的深度优先遍历算法:
【算法7.2】
VoidAdjTWGraph:
DepthFirst(intv,intvisited[])
{intvj;
Edge*p;
cout<
Vertices[v].data<
"
;
p=Vertices[v].adj;
//取v的邻接边结点
while(p!
=NULL)
{vj=p->
dest;
//取v的邻接点编号
if(visited[vj]==0)DepthFirst(vj,visited);
p=p->
next;
//取下一个邻接边结点
使用邻接链表来表示图时,其DFS算法的时间复杂度为O(n+e),此处e为无向图中边的数目或有向图中弧的数目。
图的广度优先遍历
图的广度优先遍历BFS算法是一个分层搜索的过程,和树的层序遍历算法类同,它也需要一个队列以保持遍历过的顶