当前位置:首页 » 编程语言 » 最小生成树c语言

最小生成树c语言

发布时间: 2022-05-28 16:08:26

① 急!数据结构最小生成树prim算法c语言实现

Kruskal算法:
void Kruskal(Edge E[],int n,int e)
{
int i,j,m1,m2,sn1,sn2,k;
int vset[MAXE];
for (i=0;i<n;i++) vset[i]=i; //初始化辅助数组
k=1; //k表示当前构造最小生成树的第几条边,初值为1
j=0; //E中边的下标,初值为0
while (k<n) //生成的边数小于n时循环
{
m1=E[j].u;m2=E[j].v; //取一条边的头尾顶点
sn1=vset[m1];sn2=vset[m2]; //分别得到两个顶点所属的集合编号
if (sn1!=sn2) //两顶点属于不同的集合,该边是最小生成树的一条边
{
printf(" (%d,%d):%d/n",m1,m2,E[j].w);
k++; //生成边数增1
for (i=0;i<n;i++) //两个集合统一编号
if (vset[i]==sn2) //集合编号为sn2的改为sn1
vset[i]=sn1;
}
j++; //扫描下一条边
}
}
Prim算法:
void prim(MGraph g,int v)
{
int lowcost[MAXV],min,n=g.vexnum;
int closest[MAXV],i,j,k;
for (i=0;i<n;i++) //给lowcost[]和closest[]置初值
{
lowcost[i]=g.edges[v][i];
closest[i]=v;
}
for (i=1;i<n;i++) //找出n-1个顶点
{
min=INF;
for (j=0;j<n;j++) //在(V-U)中找出离U最近的顶点k
if (lowcost[j]!=0 && lowcost[j]<min)
{
min=lowcost[j];k=j;
}
printf(" 边(%d,%d)权为:%d/n",closest[k],k,min);
lowcost[k]=0; //标记k已经加入U
for (j=0;j<n;j++) //修改数组lowcost和closest
if (g.edges[k][j]!=0 && g.edges[k][j]<lowcost[j])
{
lowcost[j]=g.edges[k][j];closest[j]=k;
}
}
}

② 求救~!C语言 最小生成树问题

普里姆算法描述:
假设 N=(V,E)是一个带权图,TE是N上最小生成树中边的集合。算法从U={u0}(u0∈V),TE={}开始,重复执行下述操作:在所有u∈U,v∈V-U的边(u,v) ∈E中找一条权值最小的边(u,v)并入集合TE,同时v并入U,直至U=V为止。此时TE中必有n-1边,则T=(V,{TE})为N的最小生成树。
为实现这个算法需附设一个辅助数组 closedge,以记录从U到V-U具有最小代价的边。对每个顶点vi∈V-U,在辅助数组中存在一个相应分量closedge[I-1],它包括两个域,其中lowcost存储该边上的权:显然, closedge[I-1].Lowcost=Min{cost(u,vi)|uEU} vex域存储该边依附的在U中的顶点。

③ C语言算法求解:对任意给定的网络(顶点数和边数自定),设计算法生成它的最小生成树。

上一个图和代码:

图1为要创建的图,图2为对应的最小生成树

代码为:

//图论之最小生成树:prim算法实现

#include"stdio.h"

#include"malloc.h"

//声明

voidoutput(structadjacentlisthead*alh,intmapsize);

structadjacentlistson//邻接表项结构体

{

intsonelement;

intquanvalue;

structadjacentlistson*next;

};

structadjacentlisthead//邻接表头结构体

{

charflag;

intelement;

intcurqvalue;

structadjacentlisthead*previous;

structadjacentlistson*startson;

};

structadjacentlisthead*mapinitialnize(intmapsize)//初始化图函数

{

structadjacentlisthead*alh=NULL;

structadjacentlistson*newnode=NULL;

inti,x,y,z;

alh=malloc(sizeof(structadjacentlisthead)*mapsize);

if(alh==NULL)

returnNULL;

for(i=0;i<mapsize;i++)

{

alh[i].flag=0;

alh[i].element=i+1;

alh[i].curqvalue=0;

alh[i].previous=NULL;

alh[i].startson=NULL;

}

scanf("%d%d%d",&x,&y,&z);

while(x&&y)//直到输入的x,y中至少有一个0为止

{

newnode=malloc(sizeof(structadjacentlistson));

newnode->sonelement=y;

newnode->quanvalue=z;

newnode->next=alh[x-1].startson;

alh[x-1].startson=newnode;

scanf("%d%d%d",&x,&y,&z);

}

returnalh;

}

intfindminnode(structadjacentlisthead*alh,intmapsize)//找到最小权值对应的结点

{

inti,minvalue=~(1<<(sizeof(int)*8-1)),minplace=0;

for(i=0;i<mapsize;i++)

{

if(alh[i].flag==0&&alh[i].curqvalue!=0)

{

if(alh[i].curqvalue<minvalue)

{

minvalue=alh[i].curqvalue;

minplace=i+1;//

}

}

}

returnminplace;

}

voidfindthemintree(structadjacentlisthead*alh,intstartplace,intmapsize)//找到最小生成树

{

structadjacentlistson*alstmp=NULL;

intcurplace=startplace;

while(curplace)

{

alstmp=alh[curplace-1].startson;

alh[curplace-1].flag=1;//正在访问

while(alstmp)

{

if(alh[alstmp->sonelement-1].flag==0)

{

if(alh[alstmp->sonelement-1].curqvalue==0||(alh[alstmp->sonelement-1].curqvalue>alstmp->quanvalue))//比较方法与有权图有一点不同

{

alh[alstmp->sonelement-1].curqvalue=alstmp->quanvalue;

alh[alstmp->sonelement-1].previous=&alh[curplace-1];

}

}

alstmp=alstmp->next;

}

curplace=findminnode(alh,mapsize);//通过函数找到最小的一个结点

}

}

voidoutput(structadjacentlisthead*alh,intmapsize)

{

inti;

for(i=0;i<mapsize;i++)

{

printf("%d点的权值为:%d ",i+1,alh[i].curqvalue);

}

printf("................................................... ");

}

intmain()

{

structadjacentlisthead*alh=NULL;

intmapsize=7,startplace=1;

alh=mapinitialnize(mapsize);

findthemintree(alh,startplace,mapsize);

output(alh,mapsize);

}

输入数据对应第一图:

122

134

141

212

243

2510

314

342

365

411

423

432

457

468

474

5210

547

576

635

648

671

744

756

761

000

④ 用prim算法求最小生成树:c语言

把main函数改成:

main(){
GraphMatrix graph = {
"abcd",

{{7,8,Max,15},{12,100,6,20},{Max,100,4,13},{Max,4,8,10}},

};

Edge mst[Max];
int i,j;

prim(graph,mst);
for(j=0;j<Max;j++)
{
printf("%c\t",mst[j].stop_vex);
printf("%c\t",mst[j].start_vex);
printf("%d\n",mst[j].weight);
}
}

还有GraphMatrix结构体里的vexs数组最好定义为vexs[VN+1]给字符串末尾的‘\0'留地方。

⑤ 求最小生成树 利用Kruskal算法求图G的一棵最小生成树T,用c语言

#include <cstdlib>
#include <iostream>
#include <queue>
using namespace std;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Description: 并查集存储结构
// Tags: 值为-1则表示为根节点
struct DisjointSet
{
int *arr;// 值为父节点下标
int number;// arr元素个数
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Description: 初始化并查集结构
// Input: number - 元素的个数
// Output:s - number个元素自成一集的并查集
void InitSet(DisjointSet &s, int number)
{
s.number = number;
s.arr = new int[number];
memset(s.arr, -1, sizeof(int) * number);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Description: 删除并查集结构
// Input: s - 并查集存储结构
// Output:s - 回收内存后的结构
void FreeSet(DisjointSet &s)
{
if (s.arr)
{
delete []s.arr;
s.number = 0;
}
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Description: 获得某个结点的根节点
// Input: s - 并查集; index - 结点下标
// Output: return - 根节点下标
int GetRoot(DisjointSet &s, int index)
{
while (s.arr[index] != -1)
index = s.arr[index];

return index;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Description: 合并index1和index2所在的两个集合
// Input: index1 - 结点1下标, index2 - 结点2下标
// Output: s - 并查集
void Union(DisjointSet &s, int index1, int index2)
{
int root1 = GetRoot(s, index1);
int root2 = GetRoot(s, index2);

s.arr[root1] = root2;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Description: 判断两个结点是否在同一个集合中
// Input: s - 并查集, index1 - 结点1下标, index2 - 结点2下标
// Output: return - true: 在 false: 不在
bool Find(DisjointSet &s, int index1, int index2)
{
return GetRoot(s, index1) == GetRoot(s, index2);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Description: 图的邻接矩阵
struct Graph
{
int **value;// 权值,-1表示无法到达
int number;
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Description: 初始化一个图
// Input: g - 图的存储结构, number - 结点个数
// Output: g - 图
void InitGraph(Graph &g, int number)
{
int i = 0;

g.value = new int *[number];
for (i = 0; i < number; i++)
g.value[i] = new int[number];

g.number = number;
memset(*g.value, -1, sizeof(int) * number * number);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Description: 回收一个图
// Input: g - 图, number - 结点个数
// Output: g - 图的存储结构
void FreeGraph(Graph &g)
{
int i = 0;

for (i = 0; i < g.number; i++)
delete []g.value[i];

delete []g.value;

g.value = 0;
g.number = 0;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Description: 为图在a,b间添加一条边
// Input:e1, e2 - 两个结点, value - 权值
// Output: graph - 加边后的图
void AddEdge(Graph &graph, int e1, int e2, int value)
{
graph.value[e1][e2] =value;
graph.value[e2][e1] = value;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Description: 显示一条边
struct OneEdge
{
OneEdge(int _a = 0, int _b = 0, int _value = 0):
a(_a), b(_b), value(_value){}

int a, b;// 边的两个结点
int value; // 边的权值
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Description: 根据权值判断两个边的大小
// Tags: 由于priority_queue是最大堆,所以这里小于号变成大于号,从而使priority_queue变成最小堆
bool operator <(OneEdge e1, OneEdge e2)
{
if (e1.value > e2.value) return true;
else return false;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Description: 用户输入图的边
// Input: n - 加边的个数
// Output: graph - 加边后的图
// Tags: Console下用户输入点对(a, b, v)
void InputEdge(Graph &graph, int n)
{
int i = 0, a, b, v;
for (i = 0; i < n; i++)
{
scanf("%d %d %d", &a, &b, &v);
AddEdge(graph, a, b, v);
}
}

int main()
{
const int NODE_NUMBER = 6;
const int EDGE_NUMBER = 9;

Graph graph;// 图
DisjointSet set;// 并查集
priority_queue<OneEdge> edge;// 2叉堆

InitGraph(graph, NODE_NUMBER);// 初始化图
InputEdge(graph, EDGE_NUMBER);
InitSet(set, NODE_NUMBER); // 初始化并查集

int i = 0, j = 0;// 初始化堆
for (i = 0; i < NODE_NUMBER; i++)
for (j = i; j < NODE_NUMBER; j++)
if (graph.value[i][j] > 0)
edge.push(OneEdge(i, j, graph.value[i][j]));

int min_pay = 0;// 最小耗费值
int add_num = 0;// 已经添加了几个边
OneEdge min_value_edge;// 当前权值最小边

while (add_num < NODE_NUMBER - 1)
{
min_value_edge = edge.top();
// 这里是因为了STL中2叉堆的结构中有一个缓冲区
// 需要将缓冲区中的每一个元素弹出来
if(min_value_edge.value > 0 && !Find(set, min_value_edge.a, min_value_edge.b))
{
Union(set, min_value_edge.a, min_value_edge.b);
min_pay += min_value_edge.value;
add_num++;
}
edge.pop();
}

printf("%d", min_pay);
return 0;
}

这个是c++语言的,最小权值存储在min_pay中,树存储在并查集set中,且在获取最小权值路径的时候用了STL中的2叉堆,算法复杂度为O(|V| * lgE)
不知是否满足您的要求

⑥ C语言数据结构的最小生成树不是唯一的吗

生成树是一个包含n个结点的连通图G的一个子图。该子图必须包含G中的所有n个结点以及G中的n-1条边并且保持连通性。
最小生成树是G的所有可能的生成树中,n-1条边的权值总和最小的那一个(或多个)生成树。

⑦ C语言(关于图最小生成树方法)

/*
邻接矩阵存储图
测试数据
610
126
131
145
235
253
345
356
364
462
566
*/

#include<stdio.h>
#include<limits.h>
#defineN100

intp[N],key[N],tb[N][N];

voidprim(intv,intn)
{
inti,j;
intmin;

for(i=1;i<=n;i++)
{
p[i]=v;
key[i]=tb[v][i];
}
key[v]=0;
for(i=2;i<=n;i++)
{
min=INT_MAX;
for(j=1;j<=n;j++)
if(key[j]>0&&key[j]<min)
{
v=j;
min=key[j];
}
printf("%d%d",p[v],v);
key[v]=0;
for(j=1;j<=n;j++)
if(tb[v][j]<key[j])
p[j]=v,key[j]=tb[v][j];
}
}

intmain()
{
intn,m;
inti,j;
intu,v,w;
while(scanf("%d%d",&n,&m))
{
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
tb[i][j]=INT_MAX;
}

while(m--)
{
scanf("%d%d%d",&u,&v,&w);
tb[u][v]=tb[v][u]=w;
}
prim(1,n);
printf(" ");
}
return0;
}

⑧ C语言,最小生成树代码,求修改

#include<stdlib.h>
#include<stdio.h>
#defineMaxVertexNum10
#defineMaxEdgeNum45

typedefstructEdgeNode
{
intFrontVertex;
intRearVertex;
intWeight;
}EdgeSet[MaxEdgeNum];

typedefintAdjmatrix[MaxVertexNum][MaxVertexNum];
intPrim();
voidInsitAdj_Prim(AdjmatrixGA);
voidSetAdj_Prim(AdjmatrixGA,intn);
voidFun_Prim(AdjmatrixGA,EdgeSetGT,intn);
voidDisplay_Prim(EdgeSetGT,intn);
voidInsit_Prim(EdgeSetGT,intn,AdjmatrixGA);
voidInsitAdj_Prim(AdjmatrixGA)
{
inti,j;
for(i=0;i<MaxVertexNum;i++)
{
for(j=0;j<MaxVertexNum;j++)
{
GA[i][j]=20000;
}
}
}

voidSetAdj_Prim(AdjmatrixGA,intn)
{
inti,j,y,w;
for(i=0;i<=n;i++)
{
for(j=i+1;j<n;j++)
{
y=i+1;
w=j+1;
printf("第%d个点到第%d个点的权值:",y,w);
scanf("%d",&GA[i][j]);
}
}
for(i=0;i<=n;i++)
{
for(j=i+1;j<n;j++)
{
GA[j][i]=GA[i][j];
}
}
}

voidFun_Prim(AdjmatrixGA,EdgeSetGT,intn)
{
inti,j,min=10000,m;
for(i=0;i<n-1;i++)
{
m=i;
for(j=i;j<n-1;j++)
{
if(GT[j].Weight<min)
{
min=GT[j].Weight;
m=j;
}
}
EdgeNodetemp=GT[i];
GT[i]=GT[m];
GT[m]=temp;
intk=GT[m].RearVertex;
for(j=i;j<n-1;j++)
{
intt=GT[j].RearVertex;
intw=GA[k][t];
if(w<GT[j].Weight)
{
GT[j].Weight=w;
GT[j].FrontVertex=k;
}
}
}
}

voidDisplay_Prim(EdgeSetGT,intn)
{
inti;
printf("保留如下弧 ");
for(i=0;i<n-1;i++)
{
inte,r;
e=GT[i].FrontVertex+1;
r=GT[i].RearVertex+1;
printf("第%d个结点到第%d个结点! ",e,r);
}
printf("可得到最小生成树");
}

voidInsit_Prim(EdgeSetGT,intn,AdjmatrixGA)
{
inti;
for(i=0;i<n-1;i++)
{
GT[i].FrontVertex=0;
GT[i].RearVertex=i+1;
GT[i].Weight=GA[0][i+1];
}
}

intPrim()
{
intn;
printf("结点数 ");
scanf("%d",&n);
EdgeSetGT;
AdjmatrixGA;
InsitAdj_Prim(GA);
SetAdj_Prim(GA,n);
Insit_Prim(GT,n,GA);
Fun_Prim(GA,GT,n);
Display_Prim(GT,n);
return0;
}

intmain(){
Prim();
}

⑨ 用prim算法的思想,用C语言编写出最小生成树的方法的代码

PrimMST(G,T,r){
//求图G的以r为根的MST,结果放在T=(U,TE)中
InitCandidateSet(…);//初始化:设置初始的轻边候选集,并置T=({r},¢)
for(k=0;k<n-1;k++){
//求T的n-1条树边
(u,v)=SelectLiShtEdge(…);//选取轻边(u,v);
T←T∪{(u,v)};//扩充T,即(u,v)涂红加入TE,蓝点v并人红点集U
ModifyCandidateSet(…);
//根据新红点v调整候选轻边集
}
}

热点内容
lol一区为什么服务器好卡 发布:2025-02-12 09:02:22 浏览:628
安卓运营商cm是哪个版本 发布:2025-02-12 09:00:00 浏览:514
pythonmd5校验 发布:2025-02-12 08:51:00 浏览:469
编程题解析 发布:2025-02-12 08:40:30 浏览:453
bilibi手机缓存目录在 发布:2025-02-12 08:33:11 浏览:457
听ti密码是多少 发布:2025-02-12 08:22:15 浏览:288
淘宝上传视频凭证 发布:2025-02-12 08:06:46 浏览:878
java画 发布:2025-02-12 08:01:00 浏览:549
光遇安卓官服是在哪里下载 发布:2025-02-12 07:47:47 浏览:648
安卓手机如何关闭程序打开广告 发布:2025-02-12 07:31:06 浏览:469