数据结构9——最小生成树

最小生成树:这里面有两个概念:(1):必须为一个树,并且为一棵生成树(树的定义有且仅有一个前驱结点,可以有有多个后驱子节点,并且(n-1)条边都在图中

                    (2):必须是最小连通的。(多一条边会使树形成回路,不满足生成树的概念,少一条边,则会使树不连通)

因此,最小生成树必须满足三个条件:

(1):必须包含n个结点

(2):必须包含(n-1) 条边

(3):不能构成回路。

最小生成树的两种构造方法:Prim算法,Kruskal算法。

1:Prim算法生成最小生成树

prim 算法的伪码描述:适合于稠密图

 1 void prim(){
 2    MST = {s};
 3    while(1){
 4      v=未收录顶点中最小dist的结点;
 5       if(v不存在)
 6        break;              //跳出循环中;
 7
 8       if(v已经收录),dist[v]=0;
 9       for(v的每一个邻接点w){
10          if(w没有被收录){              //  if(dist[w]!=0)
11             if(E(v,w)< dist[w]){
12                dist[w]= E(v,w);
13                parent[w]=v;
14     }
15 }
16    if(MST中的v不够n个){
17       不能形成最小生成树
18     }
19
20     }
21   }
22 }             

prim算法的代码描述:

 1 package com.hone.graph.MinCreateTree;
 2 import com.hone.graph.AdjMWGraph;
 3
 4 //用prim算法建立带权图g的最小生成树closeVertex
 5 public class Prim {
 6     static final int maxweight=9999;            //设置初始化权值
 7     public static void prim(AdjMWGraph g, MinSpanTree[] closeVertex ) throws Exception{
 8         int n=g.getNumOfVertices();            //获得结点的个数
 9         int minCost;
10         int[] lowCost= new int[n];            //用数组来存储最小权值边(u,v)
11         int k=0;
12
13         for (int i = 1; i < n; i++) {
14             lowCost[i]=g.getWeight(0, i);            //lowCost的初始值
15         }
16
17         MinSpanTree temp=new MinSpanTree();
18
19         //从结点0出发构造最小生成树
20         temp.vertex=g.getValue(0);
21         closeVertex[0]=temp;                    //保存结点0
22         lowCost[0]=-1;                            //用-1标记结点0,表示该结点已经加入到集合中
23
24         //寻找最小权值对应的结点k
25         for (int i = 1; i < n; i++) {
26             minCost=maxweight;                    //maxWeight为定义的最大权值
27             for (int j = 0; j < n ; j++) {
28                 if (lowCost[j]<minCost&&lowCost[j]>0) {        //获得权值更小的点
29                     minCost=lowCost[j];
30                     k=j;
31                 }
32             }
33
34             //开始构建最小生成树的当前结点和权值数据
35             MinSpanTree curr=new MinSpanTree();
36             curr.vertex=g.getValue(k);            //保存此次循环中最小权值的结点k
37             curr.weight=minCost;                //保存对应的权值
38             closeVertex[i]=curr;
39             lowCost[k]=-1;                        //标记结点k,表示该结点已经收录到最小生成树中
40
41
42             //根据加入集合中u的结点修改lowCost中的数值
43             for(int j=1; j<n; j++ ){
44                 if (g.getWeight(k, j)<lowCost[j]) {
45                     lowCost[j]=g.getWeight(k, j);
46                 }
47             }
48         }
49     }
50 }

2:Kruskal算法(克鲁斯卡尔算法)

克鲁斯卡尔算法是按照带权图中边的权值的递增顺序构造最小生成树的方法。适合于稀疏图

因此克鲁斯卡尔算法主要包括两部分:(1):带权图G中各个边的权值排序(时间复杂度的主要因素)

                 (2):判断新选择的两个结点是否会构成一个回路(避免)

克鲁斯卡尔算法的伪码描述:

时间复杂度主要在于边权重结点之间的排序。O(eloge)

时间: 2024-10-27 06:23:13

数据结构9——最小生成树的相关文章

数据结构:最小生成树--Prim算法

最小生成树:Prim算法 最小生成树 给定一无向带权图,顶点数是n,要使图连通只需n-1条边,若这n-1条边的权值和最小,则称有这n个顶点和n-1条边构成了图的最小生成树(minimum-cost spanning tree). Prim算法 Prim算法是解决最小生成树的常用算法.它采取贪心策略,从指定的顶点开始寻找最小权值的邻接点.图G=<V,E>,初始时S={V0},把与V0相邻接,且边的权值最小的顶点加入到S.不断地把S中的顶点与V-S中顶点的最小权值边加入,直到所有顶点都已加入到S中

数据结构之最小生成树

最小生成树: 一个连通图的生成树是一个极小连通子图,它含有图中全部顶点,但只有足以构成一棵树的n-1条边.这种构造连通网的最小代价生成树称为最小生成树,详见数据结构之图(术语.存储结构.遍历). 求连通网的最小生成树有两种经典方法:普里姆(Prime)算法和克鲁斯卡尔(Kruskal)算法. 1.Prime算法 (1)算法描述 假设N=(V,{E})是连通网,TE是N上最小生成树中边的集合.从V中任选一个顶点u0,算法从U={u0}(u0∈V),TE={}开始,重复执行以下步骤: 在所有u∈U.

数据结构--图--最小生成树(Prim算法)

构造连通网的最小生成树,就是使生成树的边的权值之和最小化.常用的有Prim和Kruskal算法.先看Prim算法:假设N={V,{E}}是连通网,TE是N上最小生成树中边的集合.算法从U={u0}(uo属于V),TE={}开始,重复执行下述操作:在所有u属于U,v属于V-U的边(u,v)属于E中找到代价最小的一条边(u0,v0)并入集合TE,同时v0并入U,直至U=V为止.此时TE中必有n-1条边,T={V,{TE}}为N的最小生成树.为实现此算法,需另设一个辅助数组closedge,以记录从U

白话数据结构之最小生成树

一:基本概念 1:什么是生成树? 对于图G<V,E>,如果其子图G'<V',E'>满足V'=V,且G'是一棵树,那么G'就是图G的一颗生成树.生成树是一棵树,按照树的定义,每个顶点都能访问到任何一个其它顶点.(离散数学中的概念),其中V是顶点,E是边,通俗来讲生成树必须包含原图中的所有节点且是连通的 比如 2:最小生成树 一个无向连通图G=(V,E),最小生成树就是联结所有顶点的边的权值和最小时的子图T,此时T无回路且连接所有的顶点,所以它必须是棵树.就是将原图的n个顶点用 n-1

数据结构-图-最小生成树

最小生成树表示得是连通图的极小连通子图,它包含所有的的顶点,但足以生成n-1条边的数. 下面是我学习的内容和理解. 1.使用普里姆算法构成最小生成树. 先讲一下普里姆算法的思路.普里姆算法思路是这样的: 前提:G={V,E} 这个是我们图的定义这个应该是明白啥意思的. 1.现在定义一个V1表示一个空的新集合 2.首先随机的将V中的一个节点放入到V1中,作为遍历图开始位置 3.其次选取V1中的一个节点和选取V中的一个节点,使边的权值是E中最小的(必须是存在E中的,不然不是两个节点不是连通的,也没用

数据结构例程——最小生成树的普里姆算法

本文是[数据结构基础系列(7):图]中第11课时[最小生成树的普里姆算法]的例程. (程序中graph.h是图存储结构的"算法库"中的头文件,详情请单击链接-) #include <stdio.h> #include <malloc.h> #include "graph.h" void Prim(MGraph g,int v) { int lowcost[MAXV]; //顶点i是否在U中 int min; int closest[MAXV]

数据结构:最小生成树--Kruskal算法

Kruskal算法 Kruskal算法 求解最小生成树的还有一种常见算法是Kruskal算法.它比Prim算法更直观.从直观上看,Kruskal算法的做法是:每次都从剩余边中选取权值最小的,当然,这条边不能使已有的边产生回路. 手动求解会发现Kruskal算法异常简单,以下是一个样例 先对边的权值排个序:1(0,1) 2(2,6) 4(1,3) 6(1,2) 8(3,6) 10(5,6) 12(3,5) 15(4,5) 20(0,1) 首选边1(0,1).2(2,6).4(1,3).6(1,2)

【数据结构】 最小生成树(二)——kruskal算法

上一期说完了什么是最小生成树,这一期咱们来介绍求最小生成树的算法:kruskal算法,适用于稀疏图,也就是同样个数的节点,边越少就越快,到了数据结构与算法这个阶段了,做题靠的就是速度快,时间复杂度小. 网上一搜就知道大家都会先介绍prim算法,而我为什么不介绍prim算法呢?因为小编认为这个算法理解快,也很容易明白,可以先做个铺垫(小编绝不会告诉你小编是因为不会才不说的),kruskal算法核心思想是将一棵棵树林(也可以理解成子树)合并成一棵大树,具体做法如下:将一个连通图中不停寻找最短的边,如

数据结构--画画--最小生成树(Prim算法)

通信网络的最小生成树配置,它是使右侧的生成树值并最小化.经常使用Prim和Kruskal算法.看Prim算法:以防万一N={V,{E}}它是在通信网络,TE它是N设置边的最小生成树.从算法U={u0}(uo属于V).TE={}开始,复运行下述操作:在全部u属于U.v属于V-U的边(u,v)属于E中找到代价最小的一条边(u0,v0)并入集合TE,同一时候v0并入U,直至U=V为止.此时TE中必有n-1条边,T={V,{TE}}为N的最小生成树. 为实现此算法,需另设一个辅助数组closedge,以