图 克鲁斯卡尔 Kruskal 算法生成最小生成树/C++

图 克鲁斯卡尔 Kruskal 算法生成最小生成树

基于尚硅谷韩老师java数据结构课程
本算法人为理解并不难,其实就是把所有的边按照权值进行由小到大的排序,
在把排序后的结果由小到大加起来,每加一次,进行回路判断
如果没有回路就加,有回路就跳过,进行下一条边。
我们把主要的回路判断算法放在此处。

getEnds(int[],int)

int getEnds(int ends[],int i){
	while(ends[i]!=0){
		i=ends[i];
	}
	return i;
}

韩老师说,两个结点的终点不能一致,这里如何理解终点?
就是开始生成最小生成树的时候,没加一条边,都会有两个顶点,其中每一个的顶点对应一个终点
从最小的边开始加的时候,两个顶点的终点都是"0",对应的我们需要初始化一个全是0的数组ends[g->edges],长度为边数,让每一个边的终点此时的”终点“都对应为 0,
在我们每进行一次加边的操作,我们再对这个数组进行更新。

Kruskal(Graph ,Edges )

void Kruskal(Graph g,Edges e){
	int index=0;
	int ends[g->edge]={0};//保存最小生成树中每个顶点的终点 

	//1.创建结果数组 ,保存最终的最小生成树 Res 为Result的缩写 
	Edges edgeRes =(Edges) malloc(g->edge*sizeof(struct Edge));
	
	//2.按照边的权值大小排序,我已经在main里排序过了
	
	//3.遍历edges数组从最小边开始加,加一次判回路一次,没回路就加进来(edgeRes),有回路就换下一条
	
	 for(int i =0;i<g->edge;i++) {
	 	//拿到第i条边的顶点的下标start 
		int p1= getIndex(g,e[i].start);
		//拿到第i条边的顶点的下标start 
		int p2= getIndex(g,e[i].end);
		cout<<"p1 "<<p1<<"p2 "<<p2<<endl;
		
		//获取p1顶点的在已有的最小生成树中终点是?
		int m =getEnds(ends,p1);
		//获取p2顶点的在已有的最小生成树中终点是?
		int n =getEnds(ends,p2);
		cout<<"m "<<m<<"n "<<n<<endl;
		for(int j=0;j<g->edge;j++)
		cout<<ends[i];
		cout<<endl;
		//是否构成回路
		if(m!=n) {//不构成回路 
			ends[m] =n; //设置m 在已有最小生成树的终点 
			edgeRes[index++]=e[i];
					}
	 }
	 //统计并打印最小生成树
	  for(int i =0;i<index;i++){
	  	cout<<" "<<edgeRes[i].start<<" "<<edgeRes[i].end<<" "<<edgeRes[i].weight<<endl;
	  }	
}

main()

int main(){
	int n;
	cin>>n;
	Graph graph=Create();
	Edges edges;
	edges=( Edges)malloc((n*(n-1)/2)*sizeof(struct Edge));
	for(int i=0;i<n;i++){
		char e;cin>>e;
		addVex(graph,e);
	}
		
	E v1,v2;int w;
	while(cin>>v1>>v2){
		cin>>w;
		addEdge(graph,v1,v2,w,edges);
	}

	cout<<"第一次"<<endl;
	printMatrix(graph,edges);
	qsort(edges,graph->edge, sizeof(Edge), cmp);
	cout<<"库鲁斯卡尔:"<<endl; 
	Kruskal(graph,edges);
	cout<<"排序后"<<endl;
	printMatrix(graph,edges);
	
}

整体

  #include<iostream> 
#define MAX 10
#include<malloc.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
typedef char E;
typedef struct Edge{
	E start;
	E end;
	int weight;
}*Edges;
typedef struct GraphMatrix{
	int vex,edge;
	int matrix[MAX][MAX];
	E data[MAX];
}*Graph;

Graph Create(){
	Graph g = (Graph)malloc(sizeof(GraphMatrix));
	g->vex=g->edge=0;
	memset(g->matrix,0,sizeof(g->matrix));
	return g;
}
void addVex(Graph g,E e){
	g->data[g->vex++]=e;
	
}
int getIndex(Graph g,E e){
	for(int i=0;i<g->vex;i++)
		if(g->data[i]==e)
			return i;
	return -1;
}
void addEdge(Graph g,E v1,E v2,int w,Edges e){
	int a=getIndex(g,v1);
	int b=getIndex(g,v2);
	g->matrix[a][b]=w;
	g->matrix[b][a]=w;
	
	e[g->edge].start=v1;
	e[g->edge].end=v2;
	e[g->edge].weight=w;

	g->edge++;
}
printMatrix(Graph g,struct Edge e[]){
	for(int i=0;i<g->vex;i++)
	{
		for(int j=0;j<g->vex;j++)
		 cout<<"\t"<<g->matrix[i][j];
		cout<<endl;
	}
	for(int i=0;i<g->edge;i++)
	 cout<<" "<<e[i].start<<" "<<e[i].end<<" "<<e[i].weight<<endl;
}
void Kruscal(Graph g){
	int vLen=g->vex;
}
int getEnds(int ends[],int i){
	while(ends[i]!=0){
		i=ends[i];
	}
	return i;
}
void Kruskal(Graph g,Edges e){
	int index=0;
	int ends[g->edge]={0};//保存最小生成树中每个顶点的终点 
	
	//创建结果数组 ,保存最终的最小生成树 Res 为Result的缩写 
	Edges edgeRes =(Edges) malloc(g->edge*sizeof(struct Edge));
	
	//按照边的权值大小排序,我已经在main里排序过了
	
	//遍历edges数组从最小边开始加,加一次判回路一次,没回路就加进来(edgeRes),有回路就换下一条
	
	 for(int i =0;i<g->edge;i++) {
	 	//拿到第i条边的顶点的下标start 
		int p1= getIndex(g,e[i].start);
		//拿到第i条边的顶点的下标start 
		int p2= getIndex(g,e[i].end);
		cout<<"p1 "<<p1<<"p2 "<<p2<<endl;
		
		//获取p1顶点的在已有的最小生成树中终点是?
		int m =getEnds(ends,p1);
		//获取p2顶点的在已有的最小生成树中终点是?
		int n =getEnds(ends,p2);
		cout<<"m "<<m<<"n "<<n<<endl;
		for(int j=0;j<g->edge;j++)
		cout<<ends[i];
		cout<<endl;
		//是否构成回路
		if(m!=n) {//不构成回路 
			ends[m] =n; //设置m 在已有最小生成树的终点 
			edgeRes[index++]=e[i];
			cout<<"index "<<index<<endl;
		}
	 }
	 //统计并打印最小生成树
	  for(int i =0;i<index;i++){
	  	cout<<" "<<edgeRes[i].start<<" "<<edgeRes[i].end<<" "<<edgeRes[i].weight<<endl;
	  }
	
	
}
int cmp(const void *a, const void *b){
    return ((struct Edge *)a)->weight - ((struct Edge *)b)->weight;
}




int main(){

	int n;
	cin>>n;
	Graph graph=Create();
	Edges edges;
	edges=( Edges)malloc((n*(n-1)/2)*sizeof(struct Edge));
	for(int i=0;i<n;i++){
		char e;cin>>e;
		addVex(graph,e);
	}
		
	E v1,v2;int w;
	while(cin>>v1>>v2){
		cin>>w;
		addEdge(graph,v1,v2,w,edges);
	}

	cout<<"第一次"<<endl;
	printMatrix(graph,edges);

	qsort(edges,graph->edge, sizeof(Edge), cmp);
	cout<<"库鲁斯卡尔:"<<endl; 
	Kruskal(graph,edges);
	cout<<"排序后"<<endl;
	printMatrix(graph,edges);
	
	
}
posted @ 2023-12-21 12:44  Happy_Eric  阅读(24)  评论(0编辑  收藏  举报