ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

构建最小生成树普利姆算法和克鲁斯卡尔算法(P&C)

2021-12-30 10:36:43  阅读:241  来源: 互联网

标签:普利 min int index 克鲁斯 算法 lowcost


  普利姆算法和克鲁斯卡尔算法的思想可以归为贪心算法即:以每次局部最优解最后得全局最优解。

  相同点:

    1. 都适用于无向图。
    2. 都是用了贪心思想    

  不同点:

    1. 普利姆算法是顶点优先,克鲁斯卡尔是边优先。二者应对不同情况效率不同。
    2. 普利姆算法平均时间复杂度为O(n^2),是顶点数的平方。
    3. 克鲁斯卡尔算法平均时间复杂度取决于选用的排序算法,是和边数相关的。

  普利姆算法分析如下:

   

for (int k = 0; k < g.n; k++) {
// 用邻接矩阵存储无向图, 维护一个 lowcost[],一个vset[] vset数组用于记录已经选择的顶点  
for (int i = 0; i < g.n; i++){
  //找到lowcost中 没有被选择过的最小值
  if (vset[i] == 0 && lowcast[i] < min){
    min = lowcast[i];
    min_index = i;
  }
}
// 将 min_index 点并入
vset[min_index] = 1;
//维护lowcost数组
for (int j = 0; j < g.n; j++){
  // min_index 点位新加入的点, 只要该点到其他点的距离小于 lowcost[j] 就覆盖,由此lowcost[]一直都是子树到各点的最小距离
  if (vset[j] == 0 && g.edges[min_index][j] < lowcost[j] ){
    lowcost[j] =g.edges[min_index][j];
  }
  }

}


  克鲁斯卡尔算法运用并查集工具判断是否形成回路。 并查集本质是在一个数组存了一棵二叉树,通过查找不同子节点的根节点判断是否会形成回路。

//并查集工具
public int getRoot(int a){
  // v[] 存放二叉树
  while(a != v[a]){
    a = v[a];
  }
  return a;
}
//定义边的类 包含边的左节点有节点和边的长度
class Edge{
  int leftNode;
  int rightNode;
  int length
}
//初始化并查集工具用到的数组
for (int i = 0; i < g.n; i++){
  v[i] = i;
}
// 将边按照从小到大顺序排列
sort(Edge[] edges, g.E);
for (int i = 0; i < g.e; i++){
  // 获取左右两个节点的根节点
  leftNode = getRoot(edges[i].leftNode);
  rightNode = getRoot(edges[i].rightNode);
  if (leftNode != rightNode){
    // 说明是两棵独立的子树 可以合并
    v[leftNode] = rightNode;
  }
}

  

 

标签:普利,min,int,index,克鲁斯,算法,lowcost
来源: https://www.cnblogs.com/dengsheng/p/15747714.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有