// Kruskal算法实现.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<iostream>
#define MAX 100
typedef int WeiType;
using namespace std;
//
struct Edge
{
int no; //边的序号
int x; //端点1序号
int y; // 端点2序号
WeiType weight; //权值
bool selected; //是否被选择
};
//边集和
Edge edge[MAX];
//已找到的最小生成树其中一部分的秩
int rank[MAX];
//已找到的最小生成树其中一部分的头结点
//用来判断一条边的2个端点是否在一个集合中,即加上这条边是否会形成回路
int parent[MAX];
//找出每一集合的头结点
int find_set(int x)
{
if(x != parent[x] )
parent[x] = find_set(parent[x]);
return parent[x];
}
//合并集合
void union_set(int x,int y,WeiType w,WeiType &sum)
{
if(x==y)
return;
if(rank[x]>rank[y])
parent[y]=x;
else
{
if(rank[x]==rank[y])
rank[y]++;
parent[x]=y;
}
sum +=w;
}
//依据边的权值升序快速排序
void fast_sort(Edge *edge,int begin,int end)
{
if(begin<end)
{
int i = begin-1,j=begin;
edge[0] = edge[end];
while(j<end)
{
if(edge[j].weight<edge[0].weight)
{
i++;
Edge temp1 = edge[i];
edge[i] = edge[j];
edge[j] = temp1;
}
j++;
}
Edge temp2 = edge[end];
edge[end] = edge[i+1];
edge[i+1] = temp2;
fast_sort(edge,begin,i);
fast_sort(edge,i+2,end);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int cases;
cout<<"请输入案例的个数:";
cin>>cases;
while(cases--)
{
int n;
//最小生成树的权值总和
WeiType sum = 0;
cout<<"请输入边的个数:";
cin>>n;
int i;
//初始化
char chx,chy;
WeiType weight;
for(i=1;i<=n;i++)
{
edge[i].no = i;
cout<<"请输入第"<<i<<"条边的二个端点的名称(小写字符):";
cin>>chx>>chy;
edge[i].x = chx-'a'+1;
edge[i].y = chy-'a'+1;
cout<<"这条边的权值为:";
cin>>weight;
edge[i].weight = weight;
edge[i].selected = false;
parent[edge[i].x] = edge[i].x;
parent[edge[i].y] = edge[i].y;
rank[edge[i].x] = 0;
rank[edge[i].y] = 0;
}
//快排
fast_sort(edge,1,n);
for(i=1;i<=n;i++)
{
int x,y;
x = find_set(edge[i].x);
y = find_set(edge[i].y);
//判断即加上这条边是否会形成回路
if(x != y )
{
//选择这条边
edge[i].selected = true;
//合并不会形成回路的二个集合
union_set(x,y,edge[i].weight,sum);
}
}
cout<<"最小生成树的边集为:"<<endl;
for(i=1;i<=n;i++)
{
if(edge[i].selected)
{
cout<<"序号:"<<edge[i].no<<" " <<"端点1:"<<(char)(edge[i].x+'a'-1)<<",端点2:"<<(char)(edge[i].y+'a'-1)<<endl;
}
}
cout<<"最小生成树的权值为:"<<sum<<endl;
}
system("pause");
return 0;
}
-------------------------------------------程序测试-------------------------------------------
请输入案例的个数:1
请输入边的个数:14
请输入第1条边的二个端点的名称(小写字符):a b
这条边的权值为:4
请输入第2条边的二个端点的名称(小写字符):a h
这条边的权值为:8
请输入第3条边的二个端点的名称(小写字符):b c
这条边的权值为:8
请输入第4条边的二个端点的名称(小写字符):b h
这条边的权值为:11
请输入第5条边的二个端点的名称(小写字符):c d
这条边的权值为:7
请输入第6条边的二个端点的名称(小写字符):c f
这条边的权值为:4
请输入第7条边的二个端点的名称(小写字符):c i
这条边的权值为:2
请输入第8条边的二个端点的名称(小写字符):d e
这条边的权值为:9
请输入第9条边的二个端点的名称(小写字符):d f
这条边的权值为:14
请输入第10条边的二个端点的名称(小写字符):e f
这条边的权值为:10
请输入第11条边的二个端点的名称(小写字符):f g
这条边的权值为:2
请输入第12条边的二个端点的名称(小写字符):g h
这条边的权值为:1
请输入第13条边的二个端点的名称(小写字符):g i
这条边的权值为:6
请输入第14条边的二个端点的名称(小写字符):h i
这条边的权值为:7
最小生成树的边集为:
序号:12 端点1:g,端点2:h
序号:11 端点1:f,端点2:g
序号:7 端点1:c,端点2:i
序号:1 端点1:a,端点2:b
序号:6 端点1:c,端点2:f
序号:5 端点1:c,端点2:d
序号:3 端点1:b,端点2:c
序号:8 端点1:d,端点2:e
最小生成树的权值为:37
请按任意键继续. . .
分享到:
相关推荐
编写算法能够建立带权图,并能够用Kruskal算法求该图的最小生成树。最小生成树能够选择图上的任意一点做根结点。最小生成树输出采用顶点集合和边的集合的形式。
实现了kruskal的算法,测试可行。
在本文中,我们将深入探讨Kruskal算法的原理、步骤以及C++实现。 **Kruskal算法的基本思想:** Kruskal算法遵循“贪心”策略,即在每一步选择当前未加入树中的边中权重最小的一条,并确保这条边不会形成环路。这个...
现在我们将深入探讨如何用C++实现Kruskal算法。 C++是一种广泛用于系统编程、应用软件、嵌入式系统和游戏开发的通用编程语言,其标准库提供了丰富的数据结构和算法支持,便于实现各种图论问题。 Kruskal算法的基本...
1. **引言**:介绍最小生成树的概念,以及Prim和Kruskal算法的基本思想。 2. **算法描述**:详细解释两种算法的步骤,包括伪代码或流程图。 3. **实现细节**:展示如何用编程语言(如C++、Java或Python)实现这两种...
最小生成树Kruskal算法是图论中的一个重要概念,它在计算机科学,特别是网络优化问题中有着广泛应用。本文将深入探讨Kruskal算法的基本原理、数据结构分析以及调试与分析的过程。 1. 课程设计介绍 Kruskal算法是...
综上所述,最小生成树是图论中的核心问题,Prim算法和Kruskal算法是解决该问题的两种高效方法。在C++中,这两个算法都可以利用标准库提供的功能来实现,从而在复杂度和空间效率上达到较好的平衡。理解并熟练掌握这些...
在提供的代码片段中,可以看出作者用C++实现了Kruskal算法来寻找加权无向图的最小生成树。接下来将详细介绍各个部分的功能与实现细节。 #### 数据结构定义 1. **ArcCell 结构体**: 定义了边的信息。 ```cpp ...
(1)、实验题目:给定一个地区的n 个城市间的距离网,用Prim算法或Kruskal算法建立最小生成树,并得到的最小生成树的代价。 (2)、实验要求: 1、城市间的距离网采用的邻接矩阵表示,邻接矩阵的存储结构定义采用...
图的深度优先搜索,广度优先搜索,最小生成树算法,包括kruskal、prim算法的代码,以及详细的注释。深度优先应用递归、广度优先搜索利用队列、kruskal利用STL中的关联容器set、prim算法利用二叉堆结构进行优化。
Kruskal算法是求解加权无向图最小生成树的经典算法之一,由Joseph Kruskal在1956年提出。本文将详细介绍Kruskal算法的原理、实现步骤以及C++编程实践。 **Kruskal算法的基本思想:** Kruskal算法的核心理念是逐步...
在计算机科学领域,最小生成树(Minimum...通过C++实现,我们可以有效地在实际应用中找到最小生成树,为各种问题提供解决方案。在实践中,可以结合数据结构和算法的优化技巧,如使用二叉堆或 Fibonacci heap 提升效率。
通过上述分析,我们可以看到这段代码通过Kruskal算法有效地实现了最小生成树的构建。尽管存在一定的局限性和改进空间,但对于初学者来说,它提供了一个很好的学习最小生成树概念和算法实现的基础。
洛谷原模板题p3366 题目网址: https://www.luogu.com.cn/problem/P3366
这里提到了两种常见的最小生成树算法:Prim算法和Kruskal算法。 **Prim算法** 是一种贪心策略,从一个起始顶点开始逐步构建最小生成树。在给定的代码中,Prim算法的实现主要分为以下步骤: 1. 初始化:创建一个二...
最小生成树是图论中的一个重要概念,用于...总的来说,Prim和Kruskal算法是解决最小生成树问题的两种经典方法,它们都基于贪心策略,但实现细节有所不同。掌握这两种算法及其C++实现对于理解和解决图论问题至关重要。
普利姆算法(Prim's Algorithm)和克鲁斯卡尔算法(Kruskal's Algorithm)是两种常用的求解最小生成树的方法。 1. **普利姆算法**: - 普利姆算法从一个起始顶点开始,逐步添加边,每次添加的边都是当前生成树与图...
//最小生成树的kruskal的算法 #include "stdafx.h" #include #include #include using namespace std; //int maxint=mar_maxint; class BinaryTree; class EdgeNode//边的数据结构 { private: int u,v;//边所在的...