最小生成树经典算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
最小生成树的两种经典算法的分析及实现
摘要:数据结构是计算机科学的算法理论基础和软件设计的技术基础,在计算机领域中有着举足轻重的作用,是计算机学科的核心课程。构造最小生成树有很多算法,本文主要介绍了图的概念、图的遍历,并分析了PRIM和KRUSKAL的两种经典算法的算法思想,对两者进行了详细的比较,最后用这两种经典算法实现了最小生成树的生成。
关键词:连通图,赋权图,最小生成树,算法,实现
1 前言
假设要在n个城市之间建立通信联络网,则连接n个城市只需要n-1条线路。这时,自然会考虑这样一个问题,如何在节省费用的前提下建立这个通信网?自然在每两个城市之间都可以设置一条线路,而这相应的就要付出较高的经济代价。n个城市之间最多可以设置n (n-1)/2条线路,那么如何在这些可能的线路中选择n-1 条使总的代价最小呢?可以用连通网来表示n 个城市以及n个城市之间可能设置的通信线路,其中网的顶点表示城市,边表示两个城市之间的线路,赋予边的权值表示相应的代价。对于n个顶点的连通网可以建立许多不同的生成树,每一个生成树都可以是一个通信网。现在要选择这样一棵生成树,也就是使总的代价最小。这个问题便是构造连通网的最小代价生成树(简称最小生成树)的问题。一棵生成树的代价就是树上各边的代价之和。
2图的概念
2.1 定义
无序积
在无序积中,
无向图,其中为顶点(结点)集,为边集,,中元素为无向边,简称边。
有向图,其中为顶点(结点)集,为边集,,中元素为有向边,简称边。
有时,泛指有向图或无向图。
2.2 图的表示法
有向图,无向图的顶点都用小圆圈表示。
无向边——连接顶点的线段。
有向边——以为始点,以为终点的有向线段。
2.3 概念
(1)有限图——都是有限集的图。
阶图——的图。
零图——的图。特别,若又有,称平凡图。
(2)关联 (边与点关系)——设边(或),则称与(或)关联。
无环
孤立点——无边关联的点。
环——一条边关联的两个顶点重合,称此边为环 (即两顶点重合的边)。
悬挂点——只有一条边与其关联的点,所对应的边叫悬挂边。
(3)平行边——关联于同一对顶点的若干条边称为平行边。平行边的条数称为重数。
多重图——含有平行边的图。
简单图——不含平行边和环的图。
2.4 完全图
设为阶无向简单图,若中每个顶点都与其余个顶点相邻,则
称为阶无向完全图,记作。
若有向图的任一对顶点,既有有向边,又有有向边,则
称为有向完全图。
例如:
3 图的遍历
从图中某一顶点出发访遍图中其余顶点,且使每一顶点仅被访问一次。这一过程叫做图的遍历。
遍历图的基本方法有两种:深度优先搜索和广度优先搜索。这两种方法都适用于有向图和无向图。
和树的遍历类似,图的遍历也是从某个顶点出发,沿着某条边搜索路径对图中所有顶点各作一次访问。若给定的图是连通图,则从图中任意顶点出发顺着边可以访问到该图中所有的顶点,然而,图的遍历比树的遍历复杂得多,这是因为图中的任一点都可能和其余顶点相邻接,故在访问了某个顶点之后,可能顺着某条回路又到了该顶点。为了避免重复访问同一个顶点,必须记住每个顶点是否被访问过。为此,可设置一个布尔向量visited[1..n],它的初值为false,一旦访问了顶点vi,便将visited[i]置为ture。
3.1基本概念和定理定义
定义1:图G=(V,U)的弧列u=(uu..u ) 叫做一个链;把端点重合的链叫做圈,也叫做回路。定义2:不包含圈的图称为无圈图,连通的无圈图称为树,用符号T 来表示。
定理1:在一棵树中每一对点之间只有一条路径。
定理2:有n个点的一棵树有n-1条边。
定义3:如果一棵树T 为一个连通图的子图,且包括G 中所有的点,则称该树为G 的
生成树。
定义4:对每条边e,可赋以一个实数ω(e),称为e的权,G连同它边上的权称为赋权
图。
定义5:在一个加权图中一棵生成树T 的权是T 中各个树枝的权之和,一般而言,加
权图G 中不同的生成树将有不同的权,G 的所有生成树中,权最小的那棵生成树称为G
的最小生成树,或称为G 的最优生成树。
3.2 连通图的深度优先搜索
连通图深度优先搜索的基本思想如下:假定图中某个顶点v1为出发点,首先访问出发点v1,然后任选一个v1的访问过的邻接点v2,以v2为新的出发点继续进行深度优先搜索,直至图中所有顶点被访问过。
显然,图的深度优先搜索是一个递归过程,类似于树的前序遍历,它的特点是尽可能先对纵深方向进行搜索,故称之深度优先搜索。
现以下图中G为例说明深度优搜索过程。假定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,从而遍历了图中全部顶点。在这个过程中得到的顶点的访问
v1→v2→v4→v8→v5→v3→v6→v7
这样的序列就称之为图的深度优先搜索遍历序列。
深度优先遍历算法
typedef enum{FALSE,TRUE}Boolean;//FALSE为0,TRUE为1
Boolean visited[MaxVertexNum]; //访问标志向量是全局量
void DFSTraverse(ALGraph *G)
{ //深度优先遍历以邻接表表示的图G,而以邻接矩阵表示G时,算法完全与此相同
int i;
for(i=0;i
visited[i]=FALSE; //标志向量初始化
for(i=0;i
if(!visited[i]) //vi未访问过
DFS(G,i); //以vi为源点开始DFS搜索
}//DFSTraverse
3.3 连通图的广度优先搜索
连通图广度优先搜索的基本思想是:从图中某个顶点v1出发,访问了v1之后依次访问v1的所有邻接点;并使“先被访问的顶点的领接点”先于“后被访问的顶点的领接点”被访问,直至图中所有已经被访问的顶点的领接点都被访问到。它类似于树的按层次遍历,其特点是尽可能优先对横向搜索,故称之为广度优先搜索。
下面以图中G为例说明广度优先搜索的过程。首先从起点v1出发,访问v1。v1有两个未曾访问的邻接点v2和v3。先访问v2,再访问v3。然后再先后访问v2的未曾访问过的邻接点v4、v5及v3的未曾访问过的邻接点v6、v7。最后访问v4的未曾访问过的邻接点v8。至此图中所有顶点均以被访问到。得到的顶点访问序列为:
v1→v2→v3→v4→v5→v6→v7→v8