最小生成树:构造连通网的最小代价生成树
1、Prim算法
Prim算法从图的顶点的方向出发,首先确定一个顶点,找到该顶点到任意其他顶点的连通代价,然后根据新确定的节点更新到下一个节点的连通代价。
数据结构声明:
struct Graph
{
int vertexes[MAX];
int arc[MAX][MAX];
int sum_vertexes,sum_edges;
};
构造图:
void createGraph(Graph &graph)
{
memset(graph.arc,0,sizeof(graph.arc));
int x,y,weight;
cout<<"输入顶点的总数"<<endl;
cin>>graph.sum_vertexes;
cout<<"输入边的总数"<<endl;
cin>>graph.sum_edges;
for(int i=0; i<graph.sum_vertexes; i++)
{
cout<<"输入第"<<i+1<<"个顶点的标识"<<endl;
cin>>graph.vertexes[i];
}
for(int i=0; i<graph.sum_edges; i++)
{
cout<<"输入第"<<i+1<<"条边的起点 终点 权重"<<endl;
cin>>x>>y>>weight;
graph.arc[x][y]=graph.arc[y][x]=weight;
}
}
Prim算法:
void Prim(Graph graph)
{
int adjvex[MAX];
int lowcost[MAX];
lowcost[0]=-1;
adjvex[0]=0;
//初始化
for(int i=1; i<graph.sum_vertexes; i++)
{
lowcost[i]=graph.arc[0][i];
adjvex[i]=0;
}
//lowcost :-1表示顶点已经访问,0表示两顶点不相连,其他表示权重
for(int i=1; i<graph.sum_vertexes; i++)
{
//权重<65535
int min=65535;
int k;
for(int j=1; j<graph.sum_vertexes; j++)
{
if(lowcost[j]!=-1&&lowcost[j]!=0&&lowcost[j]<min)
{
min=lowcost[j];
k=j;
}
}
lowcost[k]=-1;
cout<<adjvex[k]<<" "<<k<<endl;
//更新lowcost和adjvex
for(int j=1; j<graph.sum_vertexes; j++)
{
if(lowcost[j]!=-1&&graph.arc[k][j]!=0&&(graph.arc[k][j]<lowcost[j]||lowcost[j]==0))
{
lowcost[j]=graph.arc[k][j];
adjvex[j]=k;
}
}
}
}
2、Kruskal算法
Prim算法从定点出发,Kruskal则从边的方向考虑,将图的每一条边按照连通代价按照从小到大的方式排序,然后一次将边加入到结果中,为了避免形成环,加入一个判断机制。
数据结构声明:
struct Edge
{
int start;
int stop;
int weight;
};
struct Graph
{
Edge edge[MAX];
int sum_edges;
};
构造图:
void createGraph(Graph &graph)
{
int x,y,w;
cout<<"输入边的总数"<<endl;
cin>>graph.sum_edges;
for(int i=0;i<graph.sum_edges;i++)
{
cout<<"输入第"<<i+1<<"条边的起点 终点 权重"<<endl;
cin>>x>>y>>w;
graph.edge[i].start=x;
graph.edge[i].stop=y;
graph.edge[i].weight=w;
}
}
Kruskal算法
void sortEdges(Graph &graph)
{
Edge temp;
for(int i=0;i<graph.sum_edges;i++)
{
for(int j=i+1;j<graph.sum_edges;j++)
{
if(graph.edge[i].weight>graph.edge[j].weight)
{
temp=graph.edge[i];
graph.edge[i]=graph.edge[j];
graph.edge[j]=temp;
}
}
}
}
int Find(int *parent,int t)
{
while(parent[t]!=0)
t=parent[t];
return t;
}
void Kruskal(Graph graph)
{
int m,n;
int parent[MAX];
//初始化
for(int i=0;i<graph.sum_edges;i++)
parent[i]=0;
for(int i=0;i<graph.sum_edges;i++)
{
m=Find(parent,graph.edge[i].start);
n=Find(parent,graph.edge[i].stop);
if(m!=n)
{
parent[m]=n;
cout<<graph.edge[i].start<<" "<<graph.edge[i].stop<<" "<<graph.edge[i].weight<<endl;
}
}
}
还是写代码想让图中两个不连通的顶点之间的连通代价用0表示,结果在实现的判断中就要多添加一些条件判断,如果使用正无穷大的话,就方便多了~~~