贪婪方法——最小生成树

来源:互联网 发布:js object 键 值 编辑:程序博客网 时间:2024/06/05 19:21

离散结构中学过Prim和Kruskal算法得到最小生成树,下面不再详细介绍,直接给出代码实现

prim算法

我们用一个邻接矩阵来表示加权图

nearest[i]=Y中与vi最接近顶点的索引
distance[i]=一条边的权重,该边位于vi与索引为nearest[i]的顶点之间

void prim(int n,const number W[][],set_of_edges &f)//f为输出最小生成树中边的集合 {/*思想:先随意选择一个顶点,然后在剩下顶点中寻找与已选择顶点距离最近的顶点,(这样的选法保证了不能形成环) 然后重复以上过程 */ index i,vnear;number win;edge e;index nearest[n];//Y中与vi最接近顶点的索引 y是得到最小生成树包含的顶点 number distance[n];//一条边的权重,该边位于vi与索引为nearest[i]的顶点之间 for(i=2;i<=n;i++){nearest[i]=1;//初始化:,由于y中只含有v1,将v1设为y中离所有顶点的最近顶点 distance[i]=W[1][i];//初始化:储存所有顶点到v1的距离 用于比较 }min=∞;for(j=2;j<=n;j++){for(i=2;i<=n;i++)//找到剩下顶点中离y中最近的顶点 {if(distance[i]<min)min=distance[i];//保存最近顶点到y的最小距离 vnear=i;//保存最近顶点的编号 }  e=连接vnear和nearest[vnear]的边 将e存进f distance[vnear]=-1;//将vnear顶点标记为已使用,即 将顶点加入y中、for(i=2;i<=n;i++){if(W[i][vnear]<distance[i])//更新剩余顶点到y中顶点的最小距离 {distance[i]=W[i][vnear];nearest[i]=vnear; } }}

时间复杂度:T(n)=Θ(n^2)



kruskal算法

void kruskal(int n,int m,set_of_edges E,set_of_edges &F)//F是最小生成树包含的边的集合 {/*思路:首先把所有边按非递减的顺序排序,先选依次选择值最小的边,并检查该边是否构成环,若是则跳过此边,若否则添加此边,进行下一次循环直到覆盖所有顶点 */ index i,j;edge e;按权重的非递减顺序对E中的m条边进行排序;intial(n);//把所有顶点初始化为仅包含此顶点的集合 while(F中的边数小于n-1){e=具有最小权重的边;i,j=由e连接的顶点的索引;p=find(i);//让p指向包含vi顶点的集合 q=find(j);if(!equal(p,q))//如果两个集合不相等,则不会构成环 {merge(p,q);//把两个集合合并 将e添加到F中;  } }  } 
时间复杂度:W(n)=Θ(n^2*(lgn))

原创粉丝点击