克鲁斯卡尔算法c语言,克鲁斯卡尔算法发现求有向图出错

本文展示了图的各种遍历算法(深度优先、广度优先)以及最短路径算法(普里姆、科鲁斯卡尔、迪杰斯特拉)的C语言实现。代码包括了创建更新图、打印图的状态、以及多种寻找最优路径的方法。这些算法在图论和网络优化问题中广泛应用。
摘要由CSDN通过智能技术生成

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

void gdyx(gre*g)

{

int i,a[20];

for(i=0;iv;i++)

a[i]=0;

for(i=0;iv;i++)

if(!a[i])

gdbl(g,a,a[i]);

} void purim(gre*g)

{

int i,j,k,min,a[10],b[10];

for(i=0;iv;i++)

{

b[i]=g->sz[0][i];

a[i]=1;

}

a[0]=0;

for(i=1;iv;i++)

{

min=max;

k=0;

for(j=0;jv;j++)

if(b[j]

{

min=b[j];

k=j;

}

printf(" %c->%c(%d) ",g->vd[a[k]-1],g->vd[k],min);

a[k]=0;

for(j=0;jv;j++)

if(g->sz[k][j]

{

b[j]=g->sz[k][j];

a[j]=k+1;

}

}

} void csh(gre*g,int*a)

{

int i;

for(i=0;ih;i++)

a[i]=i;

} int cz(gre*g,int x,int*a)

{

if(a[x]!=x)

x=cz(g,a[x],a);

return x;

} void hb(int x,int y,int*a)

{

a[x]=y;

} int bcj(gre*g,int i,int j)

{

int n=0,k,a[30]={0};

csh(g,a);

i=cz(g,i,a);

j=cz(g,j,a);

if(i==j)

return 1;

else

{

hb(i,j,a);

return 0;

}

} void krusker(gre*g)

{

int i,j,count=1,k=0,n,a[10][10],b[10],c[10];

for(i=0;iv;i++)

for(j=0;jv;j++)

if(g->sz[i][j]!=max)

{

a[i][j]=g->sz[i][j];

b[k]=g->sz[i][j];

k++;

}

for(i=0;i

for(j=i+1;j

if(b[i]>b[j])

{

n=b[i];

b[i]=b[j];

b[j]=n;

}

k=0;

for(i=0;ih&&countv;i++)

{

for(j=0;jv&&countv;j++)

{

for(n=0;nv&&countv;n++)

if(b[k]==a[j][n])

{

if(!bcj(g,j,n))

{

printf(" %c->%c(%d) ",g->vd[j],g->vd[n],g->sz[j][n]);

count++;

}

break;

}

if(b[k]==a[j][n])

{

a[j][n]=max;

k++;

break;

}

}

}

} void djstl(gre*g)

{

int i,j,k,dis,min,a[20],b[20];

for(i=0;iv;i++)

{

b[i]=g->sz[0][i];

a[i]=0;

}

a[0]=1;

for(i=0;iv;i++)

{

min=max;

for(j=0;jv;j++)

if(!a[j]&&b[j]

{

min=b[j];

k=j;

}

a[k]=1;

for(j=0;jv;j++)

if(!a[j])

{

dis=b[k]+g->sz[k][j];

b[j]=(b[j]

}

}

for(i=0;iv;i++)

printf(" ->%c(%d)",g->vd[i],b[i]);

printf("\n");

} void zylx(gre*g)

{

sd q;

int i,j,k,a[10];

cld(&q);

for(i=0;iv;i++)

a[i]=0;

printf("%c ",g->vd[0]);

a[0]=1;

rrd(&q,0);

while(!ddk(&q))

{

k=ccd(&q);

for(i=0;iv;i++)

if(!a[i]&&g->sz[k][i]!=max)

{

printf("->%c",g->vd[i]);

rrd(&q,i);

a[i]=1;

}

}

printf("\n");

while(q.dw->pre)

{

printf("%c ",g->vd[q.dw->data]);

q.dw=q.dw->pre;

}

printf("\n");

} main()

{

char ch1,ch2;

int i,j;

gre g;

ch1='y';

printf("请选择下列选项!!");

while(ch1=='y'||ch1=='Y')

{

printf("\nA----创建更新图!!\n");

printf("B----图的存储状态!!\n");

printf("C----深度优先遍历!!\n");

printf("D----广度优先遍历!!\n");

printf("E----普里姆算法最短路径!!\n");

printf("F----科鲁斯卡尔算法最短路径!!\n");

printf("G----迪杰斯特拉最短路径!!\n");

printf("H----最优路线!!\n");

printf("I----退出!!\n");

scanf(" %c",&ch2);

switch(ch2)

{

case'A':

case'a':cjgxt(&g);

printf("图创建或更新完成!!\n\n");

break;

case'B':printf("现在存储状态如下:\n");

case'b':tczt(&g);break;

case'C':printf("深度优先遍历!!\n");

case'c':sdyx(&g);break;

case'D':printf("广度优先遍历!!\n");

case'd':gdyx(&g);break;

case'E':printf("普里姆算法最短路径!!\n");

case'e':purim(&g);break;

case'F':printf("科鲁斯卡尔算法最短路径!!\n");

case'f':krusker(&g);break;

case'G':printf("迪杰斯特拉最短路径!!\n");

case'g':djstl(&g);break;

case'H':printf("最优路线!!\n");

case'h':zylx(&g);break;

case'I':printf("退出!!\n");

case'i':exit(1);

default:printf("请选择正确的选项!!\n");

}

printf("结束请按N,继续请按Y\n");

scanf(" %c",&ch1);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的C语言程序实现克鲁斯卡尔算法最小生成树的过程: ```c #include <stdio.h> #include <stdlib.h> // 定义边的结构体 struct Edge { int start, end, weight; }; // 定义并查集结构体 struct UnionFind { int *parent; int count; }; // 初始化并查集 void initUnionFind(struct UnionFind *uf, int n) { uf->parent = malloc(sizeof(int) * n); uf->count = n; for (int i = 0; i < n; i++) { uf->parent[i] = i; } } // 查找并查集的根节点 int find(struct UnionFind *uf, int x) { while (x != uf->parent[x]) { uf->parent[x] = uf->parent[uf->parent[x]]; x = uf->parent[x]; } return x; } // 合并两个并查集 void merge(struct UnionFind *uf, int p, int q) { int rootP = find(uf, p); int rootQ = find(uf, q); if (rootP == rootQ) return; uf->parent[rootP] = rootQ; uf->count--; } // 比较函数,用于qsort排序 int cmp(const void *a, const void *b) { struct Edge *e1 = (struct Edge *)a; struct Edge *e2 = (struct Edge *)b; return e1->weight - e2->weight; } // 克鲁斯卡尔算法最小生成树 void kruskal(struct Edge *edges, int n, int m) { // 按边权从小到大排序 qsort(edges, m, sizeof(struct Edge), cmp); // 初始化并查集 struct UnionFind uf; initUnionFind(&uf, n); // 遍历每条边 for (int i = 0; i < m; i++) { int start = edges[i].start; int end = edges[i].end; int weight = edges[i].weight; // 如果两个点不在同一个并查集中,则将它们合并,并输出这条边 if (find(&uf, start) != find(&uf, end)) { merge(&uf, start, end); printf("%d -> %d, weight = %d\n", start, end, weight); } // 如果并查集中只剩下一个节点,说明已经生成了最小生成树 if (uf.count == 1) break; } } int main() { // 假设有5个点,7条边 int n = 5, m = 7; // 定义边的数组 struct Edge edges[] = { {0, 1, 2}, {0, 3, 6}, {1, 2, 3}, {1, 3, 8}, {1, 4, 5}, {2, 4, 7}, {3, 4, 9} }; // 调用克鲁斯卡尔算法最小生成树 kruskal(edges, n, m); return 0; } ``` 这个程序实现了一个简单的克鲁斯卡尔算法,用于无向图的最小生成树。在程序中,我们定义了边的结构体和并查集结构体,分别用于存储图的边和维护并查集。首先按照边权从小到大排序,然后遍历每条边,如果两个端点不在同一个并查集中,则将它们合并,并输出这条边。最终,程序输出的所有边就是最小生成树的边。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值