大二数据结构第七次总结---图

                                                      图

1.图的定义

图是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:

G=(V,E)

其中:G表示一个图,V是图G中顶点的集合,E是图G中顶点之间边的集合。

 

 

2.图的基本术语 

简单图:在图中,若不存在顶点到其自身的边,且同一条边不重复出现。

邻接、依附

无向图中,对于任意两个顶点vi和顶点vj,若存在边(vi,vj),则称顶点vi和顶点vj互为邻接点,同时称边(vi,vj)依附于顶点vi和顶点vj。

邻接、依附

有向图中,对于任意两个顶点vi和顶点vj,若存在弧<vi,vj>,则称顶点vi邻接到顶点vj,顶点vj邻接自顶点vi,同时称弧<vi,vj>依附于顶点vi和顶点vj 。 

无向完全图:在无向图中,如果任意两个顶点之间都存在边,则称该图为无向完全图。

有向完全图:在有向图中,如果任意两个顶点之间都存在方向相反的两条弧,则称该图为有向完全图。  

稀疏图:称边数很少的图为稀疏图;

稠密图:称边数很多的图为稠密图。

顶点的度:在无向图中,顶点v的度是指依附于该顶点的边数,通常记为TD (v)。

顶点的入度:在有向图中,顶点v的入度是指以该顶点为弧头的弧的数目,记为ID (v);

顶点的出度:在有向图中,顶点v的出度是指以该顶点为弧尾的弧的数目,记为OD (v)。

权:是指对边赋予的有意义的数值量。

网:边上带权的图,也称网图。

路径:在无向图G=(V, E)中,从顶点vp到顶点vq之间的路径是一个顶点序列(vp=vi0,vi1,vi2, …, vim=vq),其中,(vij-1,vij)∈E(1≤j≤m)。若G是有向图,则路径也是有方向的,顶点序列满足<vij-1,vij>∈E。

回路(环):第一个顶点和最后一个顶点相同的路径。

简单路径:序列中顶点不重复出现的路径。

简单回路(简单环):除了第一个顶点和最后一个顶点外,其余顶点不重复出现的回路。

 

连通分量:非连通图的极大连通子图称为连通分量。 

强连通图:在有向图中,对图中任意一对顶点vi和vj (i≠j),若从顶点vi到顶点vj和从顶点vj到顶点vi均有路径,则称该有向图是强连通图。

强连通分量:非强连通图的极大强连通子图。 

生成树:n个顶点的连通图G的生成树是包含G中全部顶点的一个极小连通子图。 

生成森林:在非连通图中,由每个连通分量都可以得到一棵生成树,这些连通分量的生成树就组成了一个非连通图的生成森林。 

 

 

3.深度优先遍历 (DFS:Depth First Search)

基本思想 :

⑴ 访问顶点v;

⑵ 从v的未被访问的邻接点中选取一个顶点w,从w出发进行深度优先遍历;

⑶ 重复上述两步,直至图中所有和v有路径相通的顶点都被访问到。

4.广度优先遍历 (BFS:Broad First Search ;FIFO: First In First Out)

基本思想:

⑴ 访问顶点v;

⑵ 依次访问v的各个未被访问的邻接点v1, v2, …, vk;

⑶ 分别从v1,v2,…,vk出发依次访问它们未被访问的邻接点,并使“先被访问顶点的邻接点”先于“后被访问顶点的邻接点”被访问。直至图中所有与顶点v有路径相通的顶点都被访问到。

5.邻接矩阵(数组表示法)

基本思想:

用一个一维数组存储图中顶点的信息

用一个二维数组(称为邻接矩阵)存储图中各顶点之间的邻接关系。

6.邻接矩阵中图的基本操作——构造函数

MGraph(T a[ ], int n, int e );

1确定图的顶点个数和边的个数;

2输入顶点信息存储在一维数组vertex中;

3初始化邻接矩阵;

依次输入每条边存储在邻接矩阵arc中;

     4.1 输入边依附的两个顶点的序号i, j;

     4.2 将邻接矩阵的第i行第j列的元素值置为1;

     4.3 将邻接矩阵的第j行第i列的元素值置为1;

template <class T>

MGraph::MGraph(T a[ ], int n, int e) {

    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;  //置有边标志   

    }

}

7.邻接矩阵中图的基本操作——深度优先遍历

⑴ 访问顶点v;

⑵ 从v的未被访问的邻接点中选取一个顶点w,从w出发进行深度优先遍历;

⑶ 重复上述两步,直至图中所有和v有路径相通的顶点都被访问到。

递归定义

int visited[MaxSize];

template <class T>

void MGraph::DFSTraverse(int v){

     cout<<vertex[v]; visited [v]=1;

     for (j=0; j<vertexNum; j++)

         if (arc[v][j]==1 && visited[j]==0)

            DFSTraverse( j );

}

7.邻接矩阵中图的基本操作——广度优先遍历

⑴ 访问顶点v;

⑵ 依次访问v的各个未被访问的邻接点v1, v2, …, vk;

⑶ 分别从v1,v2,…,vk出发依次访问它们未被访问的邻接点,并使“先被访问顶点的邻接点”先于“后被访问顶点的邻接点”被访问。直至图中所有与顶点v有路径相通的顶点都被访问到。

 

 

8.邻接表存储的基本思想:

对于图的每个顶点vi,将所有邻接于vi的顶点链成一个单链表,称为顶点vi的边表(对于有向图则称为出边表)

所有边表的头指针和存储顶点信息的一维数组构成了顶点表。

邻接表有两种结点结构:顶点表结点和边表结点。

vertex:数据域,存放顶点信息。

firstedge:指针域,指向边表中第一个结点。

adjvex:邻接点域,边的终点在顶点表中的下标。

next:指针域,指向边表中的下一个结点。

9.定义邻接表的结点 

struct ArcNode{  

      int adjvex;

      ArcNode *next;

};

template <class T>

struct VertexNode{

      T vertex;

      ArcNode *firstedge;

};

10.邻接表中图的基本操作——构造函数 

1. 确定图的顶点个数和边的个数;

2. 输入顶点信息,初始化该顶点的边表;

3. 依次输入边的信息并存储在边表中;

     3.1  输入边所依附的两个顶点的序号i和j;

     3.2  生成邻接点序号为j的边表结点s;

   3.3 将结点s插入到第i个边表的头部;

template <class T>

ALGraph::ALGraph(T a[ ], int n, int e)

{  

    vertexNum=n; arcNum=e;

    for (i=0; i<vertexNum; i++)  

    {

       adjlist[i].vertex=a[i];

       adjlist[i].firstedge=NULL;     

    }

        for (k=0; k<arcNum; k++)  

     {

         cin>>i>>j;   

         s=new ArcNode; s->adjvex=j;             

         s->next=adjlist[i].firstedge;   

         adjlist[i].firstedge=s;

     }

}

 

 

 

11.顶点表结点

vertex:数据域,存放顶点信息;

firstin:入边表头指针;

firstout:出边表头指针;

12.边表结点

tailvex:弧的起点在顶点表中的下标;

headvex:弧的终点在顶点表中的下标;

headlink:入边表指针域;

taillink:出边表指针域。

 

 

13.最小生成树(minimal spanning tree)

生成树的代价:设G=(V,E)是一个无向连通网,生成树上各边的权值之和称为该生成树的代价。

最小生成树:在图G所有生成树中,代价最小的生成树称为最小生成树。 

性质:

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

14.普里姆(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。

Prim算法——伪代码 

1. 初始化两个辅助数组lowcost(=arc[0][i])和adjvex(=0)(0是始点);

2. 输出顶点u0,将顶点u0加入集合U中;

3. 重复执行下列操作n-1次

   3.1 在lowcost中选取最短边(lowcost[k]),取对应的顶点序号k;

   3.2 输出顶点k和对应的权值;

   3.3 将顶点k加入集合U中(lowcost[k]=0);

   3.4 调整数组lowcost和adjvex;

15.克鲁斯卡尔(Kruskal)算法 

基本思想:

设无向连通网为G=(V, E),令G的最小生成树为T=(U, TE),其初态为U=V,TE={ },

然后,按照边的权值由小到大的顺序,考察G的边集E中的各条边。

若被考察的边的两个顶点属于T的两个不同的连通分量,则将此边作为最小生成树的边加入到T中,同时把两个连通分量连接为一个连通分量;

若被考察边的两个顶点属于同一个连通分量,则舍去此边,以免造成回路,

如此下去,当T中的连通分量个数为1时,此连通分量便为G的一棵最小生成树。

16.最短路径:

在非网图中,最短路径是指两顶点之间经历的边数最少的路径。

在网图中,最短路径是指两顶点之间经历的边上权值之和最短的路径。

17.Dijkstra算法

基本思想:

设置一个集合S存放已经找到最短路径的顶点,S的初始状态只包含源点v,

对vi∈V-S,假设从源点v到vi的有向边为最短路径(从v到其余顶点的最短路径的初值)。

以后每求得一条最短路径v, …, vk,就将vk加入集合S中,并将路径v, …, vk , vi与原来的假设相比较,取路径长度较小者为最短路径。

重复上述过程,直到集合V中全部顶点加入到集合S中。

路径长度最短的最短路径(即第一条最短路)的特点:

   在这条路径上,必定只含一条边,并且这条边上的权值最小。 

下一条路径长度次短的最短路径的特点:

它只可能有两种情况:

或者是直接从源点到该点(只含一条边);

或者是从源点经过顶点v1(第一条最短路径所依附的顶点),再到达该顶点(由两条边组成)。

再下一条路径长度次短的最短路径的特点:

   它可能有四种情况:或者是直接从源点到该点(只含一条边); 或者从源点经过顶点v1,再到达该顶点(由两条边组成);或者是从源点经过顶点v2,再到达该顶点(两条条边);或者是从源点经过顶点v1、v2,再到达该顶点(多条边)。

其余最短路径的特点:

   它或者是直接从源点到该点(只含一条边); 或者是从源点经过已求得最短路径的顶点(集合S中的顶点),再到达该顶点。

 

 

18.图的存储结构:邻接矩阵存储结构  

数组dist[n]:每个分量dist[i]表示当前所找到的从始点v到终点vi的最短路径的长度。初态为:

                                 若从v到vi有弧,则dist[i]为弧上权值;否则置dist[i]为∞。

数组path[n]:path[i]是一个字符串,表示当前所找到的从始点v到终点vi的最短路径。初态为:若从v到vi有弧,则path[i]为vvi;否则置path[i]空串。

数组s[n]:存放源点和已经找到最短路径的终点,其初态为只有一个源点v。

 

19.拓扑序列:

设G=(V,E)是一个具有n个顶点的有向图,V中的顶点序列v1, v2, …, vn称为一个拓扑序列,当且仅当满足下列条件:若从顶点vi到vj有一条路径,则在顶点的拓扑序列中顶点vi必在顶点vj之前。

20.拓扑排序:对一个有向图构造拓扑序列的过程称为拓扑排序 。

基本思想:

⑴ 从AOV网中选择一个没有前驱的顶点并且输出;

⑵ 从AOV网中删去该顶点,并且删去所有以该顶点为尾的弧;

⑶ 重复上述两步,直到全部顶点都被输出,或AOV网中不存在没有前驱的顶点。

21.基于邻接表的拓扑排序的基本思想

(1)找G中无前驱的顶点

查找indegree [i]为零的顶点vi;

(2)修改邻接于顶点i的顶点的入度(删除以i为起点的所有弧)对链在顶点i后面的所有邻接顶点k,将对应的indegree[k] 减1。

       为了避免重复检测入度为零的顶点,可以再设置一个辅助栈,若某一顶点的入度减为0,则将它入栈。每当输出某一入度为0的顶点时,便将它从栈中删除。

22.拓扑排序算法——伪代码

1. 栈S初始化;累加器count初始化;

2. 扫描顶点表,将没有前驱的顶点压栈;

3. 当栈S非空时循环

       3.1 vj=退出栈顶元素;输出vj;累加器加1;

       3.2 将顶点vj的各个邻接点的入度减1;

       3.3 将新的入度为0的顶点入栈;

4. if (count<vertexNum) 输出有回路信息;

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值