最小生成树算法(一).docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
最小生成树算法(一)

最小生成树算法及C语言实现(一) 本文主要讲述最小生成树的概念和相应的算法原理和证明,包含了Prim算法的C实现,其它实现方式会在“最小生成树算法及C语言实现(二)”中讲到。 最小生成树(Minimum Spanning Tree, MST)对于有向图也是有意义的,但那比较难,下文只讨论无向图的情况。 简单地说,生成树就是使用原来图上的所有或者部分边把图上所有点相连的树。 简单地说,最小生成树就是使用原来图上的所有或者部分边并通过最少的总路径把图上所有点相连(可以间接相连)得到的树。 定理: 生成树存在当且仅当图是连通的。 证明: 如果图不是连通的,则显然不存在最小生成树。对于一个连通的图来说,如果它已经是树,则本身即是一棵生成树,如果它的某部分形成了环,则把相应的环去掉,则可以得到一颗生成树。 定理: 最小生成数存在当且仅当图是连通的。 证明: 由上面的定理可以直接得到。 定理: 一个N个顶点的图的最小生成树的边的数量为N-1。 证明: 最小生成树没有环,所以是一棵树,对于一棵树而言,我们可以选定一个根结点,那么,除了根结点外,其它结点有且仅有一条边连向它的父结点,所以共N-1条边。 同样,为了简单起见,下文假设图是连通的。以下的两个经典算法都是通过贪心算法的原理实现的。贪心算法对于MST是成立的,这在下面会证明。 Prim 算法 Prim算法的步骤非常简单: 选择任意一个顶点为根,并把它做为一棵树。 在任意状态下,选择在树上的一点和不在树上的一点构成的边中最短的一条边使树得以伸长。 定理: Prim算法可以用于产生MST。 证明:设G是一个连通的具有n个顶点的有权图。我们知道Prim算法最终会生成一棵n个顶点的树(由上述过程,是不会生成环的,因为形成环必然要连接已经在树上的两个结点),不妨记N-1条边为E1,E2,E3,...,En-1,其中序号沿着树生成时的每条边产生的序号。我们再记Sk为E1,E2,E3,...,EK(k是一个变量,可以进行取值)构成的树。我们再记一棵和S最相接近的最小生成树T(即两者包含的边尽量一致),它包含了E1,E2,E3,...,EK这几条Sk的边(如k取3表示T和S有3条边相同,k = n-1表示T和S完全相同,当然,如果T和S完全不同,k可能取0)。我们接下来证明S = T。 假设S ≠ T.那么必然有k n-1。即T包含了E1,E2,E3,...,EK却不包含Ek+1。我们在T上加上Ek+1使形成一个新的图,这个图含有n条边,但它只有n个顶点,所以它已经不是树,它形成了环,这个环的成员里有Ek+1,因为没有它时T还是树而没有环。而Ek+1在Sk+1里是不成环的,而Ek+1有一个顶点V在Sk中,所以这个环中有一条与Ek+1通过V相邻的一条边E不属于Sk+1。我们从T中去除边E,加上Ek+1形成新的树T。 T显然是一棵树,因为它的环的一条边被去除了。要注意由于E不在Sk+1中,我们当初进行Prim算法循环的时候,可以选择E或者Ek+1,因为两条边同时含有顶点V在Sk中。按照算法的原则,当初选择Ek+1的唯一可能原因是Ek+1 = E.所以T的总路径 - T的总路径 = Ek+1 - E = 0.而T的总路径是最小的,所以T 也是最小生成树,由此T才是与S最接近的最小生成树,所以产生矛盾,即S = T正确。 算法实现思路1:Prim 邻接矩阵 我们先通过邻接矩阵来实现Prim算法,我们对于每一个点,要对它的所有相邻点进行遍历并记录,接下来选择最短的边的顶点,它已经在树上了,对它所有相邻点进行遍历,不断重复这个过程,由于每次必定会找到一条边,所以包括选择顶点总的遍历次数为V次,我们要通过Known[]数组来判断一个顶点是否已经在树上,我们还可以通过Path[]数组获得到达相应顶点的路径。此时对于每个顶点都要遍历与它相邻的所有顶点,时间复杂度为O(V2),其中V为图的顶点数。为了方便,下面使用C语言的代码而不是C++的模版函数。下面的代码给出了较为完整的注释,所以这里便不解释了,从代码中也可以方便地看出时间复杂度。 typedef double ElementType; #define MaxV 100 #define Infinity 1000000 ElementType Prim_MST(int V, ElementType Graph[][MaxV],int Path[]) //传递Path[]用于在函数外部获得路径 { ElementType MinLength = 0, MinVertex[MaxV]; int MinTemp ,Known[MaxV]; //MinLength作为函数的返回值,表示MST所有边的总长度 //MinVertex[]用于记录目前可以到达这个顶点的最短边长

文档评论(0)

yan698698 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档