关于#c语言#的问题:这是一个用快排和kruskal算法的求最小树的代码


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define INF 10000
#define MAXV 6
#define MAXSIZE 10;
typrdef struct
{ 
 int no;//顶点编号 
 InFoType into;
}VertexType;

typedef struct
{
    int edge[MAXV][MAXV];
    int n,e;
    VertexType vexs[MAXV];
}MatGraph;


typedef struct
{
    int u;
    int v;
    int w;
}Edge;

typedef struct
{
    int key;
    int a;
    int b;
}ReeType;

int partition(RecType R[],int s,int t)
{
    int i=s,j=t;
    RecType base=R[i];
    while(i<j)
    {
        while(j>i&&R[i].key>=base.key)
        j--;
        if(i<j)
        {
            R[i]=R[j];
            i++;
        }
        while(j>i&&R[i].key<base.key)
        i++;
        if(i<j)
        {
            R[i]=R[j];
            j--;
        }
        
    }
    R[i]=base;
    return i;
    
}

void QuickSort(RecType R[],int s,int t)
{
    int i;
    if(s<t)
    {
        i=partition(R,s,t);
        QuickSort(R,s,i-1);
        QuickSort(R,i+1,t);
    }
}

void Kruskal(MatGraph g)
{
    int i,j,u1,v1,sn1,sn2,k;
    int vest[MAXV];
    Edge E[10];
    k=0;
    for(i=0;i<g.n;i++)
    {
        for(j=0;j<=i;j++)
        if(g.edge[i][j]!=0&&g.edge[i][j]!=INF)
        {
            E[k].u=i;
            E[k].v=j;
            E[k].w=g.edge[i][j];
            k++;
        }
    }
    
    QuickSort(E,u,v);
    for(i=0;i<g.n;i++)
    vest[i]-i;
    k=1;
    j=0;
    while(k=g.n)
    {
        u1=E[j].u;
        v1=E[j].v;
        sn1=vset[u1];
        sn2=vset[v1];
        if(sn1!=sn2)
        {
            printf("(%d,%d):%d\n",u1,v1,E[j],w);
            k++;
            for(i=0;i<g.n;i++)
            if(vset[i]==sn2)
            vset[i]=sn1;
            
        }
        
        j++;
        
    }
    
}

int main()
{
    MatGraph g;
    MatGraph.edge={{0,6,1,5,10000,10000},{6,0,3,10000,3,10000},{1,3,0,5,6,4},{5,10000,5,0,10000,2},{10000,3,6,10000,0,6},{10000,10000,4,2,6,0}};
    int n=5,e=10;
    MatGraph.vexs={1,2,3,4,5,6};
    
    Kruskal(g);
    
    
    
};

这是一个用快排和kruskal算法的求最小树的代码,帮忙修改一下

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
这份代码中有一些语法和逻辑错误,我将对其进行修正。

  1. 在代码中的第4行,typrdef应该改为typedef

  2. 在代码中的第9行,InFoType没有定义,应该将其改为一个具体的数据类型,例如int

  3. 在代码中的第20行和第25行,ReeType应该改为RecType

  4. 在代码中的第30行,QuickSort函数的参数声明应该改为RecType R[],因为之前已经定义了RecType

  5. 在代码中的第43行,uv没有声明,应该改为int u, v

  6. 在代码中的第45行,vset没有声明,应该改为vest

  7. 在代码中的第53行,k=g.n应该改为k==g.n

  8. 在代码中的第54行,vset[u1]应该改为vest[u1]

  9. 在代码中的第55行,vset[v1]应该改为vest[v1]

  10. 在代码中的第68行,应该在main函数后加上一对大括号。

下面是修正后的代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define INF 10000
#define MAXV 6

typedef struct {
    int no; // 顶点编号
    int info;
} VertexType;

typedef struct {
    int edge[MAXV][MAXV];
    int n, e;
    VertexType vexs[MAXV];
} MatGraph;

typedef struct {
    int u;
    int v;
    int w;
} Edge;

typedef struct {
    int key;
    int a;
    int b;
} RecType;

int partition(RecType R[], int s, int t) {
    int i = s, j = t;
    RecType base = R[i];
    while (i < j) {
        while (j > i && R[j].key >= base.key) j--;
        if (i < j) {
            R[i] = R[j];
            i++;
        }
        while (j > i && R[i].key < base.key) i++;
        if (i < j) {
            R[j] = R[i];
            j--;
        }
    }
    R[i] = base;
    return i;
}

void QuickSort(RecType R[], int s, int t) {
    int i;
    if (s < t) {
        i = partition(R, s, t);
        QuickSort(R, s, i - 1);
        QuickSort(R, i + 1, t);
    }
}

void Kruskal(MatGraph g) {
    int i, j, u, v, sn1, sn2, k;
    int vest[MAXV];
    Edge E[10];
    k = 0;
    for (i = 0; i < g.n; i++) {
        for (j = 0; j <= i; j++) {
            if (g.edge[i][j] != 0 && g.edge[i][j] != INF) {
                E[k].u = i;
                E[k].v = j;
                E[k].w = g.edge[i][j];
                k++;
            }
        }
    }

    QuickSort(E, 0, k - 1);
    for (i = 0; i < g.n; i++)
        vest[i] = i;
    k = 1;
    j = 0;
    while (k < g.n) {
        u = E[j].u;
        v = E[j].v;
        sn1 = vest[u];
        sn2 = vest[v];
        if (sn1 != sn2) {
            printf("(%d,%d):%d\n", u, v, E[j].w);
            k++;
            for (i = 0; i < g.n; i++)
                if (vest[i] == sn2) vest[i] = sn1;
        }
        j++;
    }
}

int main() {
    MatGraph g;
    g.edge[0][0] = 0; g.edge[0][1] = 6; g.edge[0][2] = 1; g.edge[0][3] = 5; g.edge[0][4] = INF; g.edge[0][5] = INF;
    g.edge[1][0] = 6; g.edge[1][1] =0; g.edge[1][2] = 3; g.edge[1][3] = INF; g.edge[1][4] = 3; g.edge[1][5] = INF;
    g.edge[2][0] = 1; g.edge[2][1] = 3; g.edge[2][2] = 0; g.edge[2][3] = 5; g.edge[2][4] = 6; g.edge[2][5] = 4;
    g.edge[3][0] = 5; g.edge[3][1] = INF; g.edge[3][2] = 5; g.edge[3][3] = 0; g.edge[3][4] = INF; g.edge[3][5] = 2;
    g.edge[4][0] = INF; g.edge[4][1] = 3; g.edge[4][2] = 6; g.edge[4][3] = INF; g.edge[4][4] = 0; g.edge[4][5] = 6;
    g.edge[5][0] = INF; g.edge[5][1] = INF; g.edge[5][2] = 4; g.edge[5][3] = 2; g.edge[5][4] = 6; g.edge[5][5] = 0;
    g.n = 6;
    g.vexs[0].no = 1; g.vexs[1].no = 2; g.vexs[2].no = 3; g.vexs[3].no = 4; g.vexs[4].no = 5; g.vexs[5].no = 6;

    Kruskal(g);

    return 0;
}

这份代码修正后应该可以正确执行了。需要注意的是,输入的图是一个无向连通图,其邻接矩阵的对称性需要保证。此外,图中的边权值应该是非负整数,因为快排算法的实现中使用了等于号。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

  • 建议你看下这篇博客👉 :Kruskal算法实现
  • 除此之外, 这篇博客: 最小生成树kruskal算法中的 代码 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • #include <stdio.h>
    #define MAXE 100
    #define MAXV 100
    typedef struct{ 
    	int vex1;  //边的起始顶点 
    	int vex2;  //边的终止顶点 
    	int weight; //边的权值 
    }Edge;
    void kruskal(Edge E[],int n,int e)
    { 
    	int i,j,m1,m2,sn1,sn2,k,sum=0;
    	int vset[n+1];
    	for(i=1;i<=n;i++) //初始化辅助数组 
    		vset[i]=i;
    	k=1;//表示当前构造最小生成树的第k条边,初值为1 
      	j=0;//E(边集)中边的下标,初值为0
       while(k<e)//生成的边数小于e时继续循环 
       {
           m1=E[j].vex1;
           m2=E[j].vex2;//取一条边的两个邻接点 
           sn1=vset[m1];
           sn2=vset[m2];                           
    	       //分别得到两个顶点所属的集合编号 
    	    if(sn1!=sn2)//两顶点分属于不同的集合,该边是最小生成树的一条边  
    	    {//防止出现闭合回路 
    			printf("V%d-V%d=%d\n",m1,m2,E[j].weight);
    			sum+=E[j].weight;
    			k++;   //生成边数增加 
    			if(k>=n)
    				break;
    			for(i=1;i<=n;i++)    //两个集合统一编号
    				if (vset[i]==sn2)  //集合编号为sn2的改为sn1
    					vset[i]=sn1;
    	    }
         j++;//扫描下一条边 
       }
        printf("最小权值之和=%d\n",sum);
    }
    int fun(Edge arr[],int low,int high)
     {
     	int key;
     	Edge lowx;
     	lowx=arr[low];
     	key=arr[low].weight;
     	while(low<high)
     	{
     		while(low<high && arr[high].weight>=key)
     			high--;
     		if(low<high)
     			arr[low++]=arr[high];
    
     		while(low<high && arr[low].weight<=key)
     			low++;
     		if(low<high)
     			arr[high--]=arr[low];
    	 }
    	 arr[low]=lowx;
    	 return low;
      } 
    void quick_sort(Edge arr[],int start,int end)
    {
    	int pos;
    	if(start<end)
    	{
    	pos=fun(arr,start,end);
    	quick_sort(arr,start,pos-1);
    	quick_sort(arr,pos+1,end);
    	}
    }
    int main()
    {
    	Edge E[MAXE];
    	int nume,numn;
    	printf("输入顶数和边数:\n");
    	scanf("%d%d",&numn,&nume);
    	for(int i=0;i<nume;i++)
    		scanf("%d%d%d",&E[i].vex1,&E[i].vex2,&E[i].weight);
    	quick_sort(E,0,nume-1);
    	kruskal(E,numn,nume);
    }
    //INPUT要输入的:
    //6 10
    //1 2 6
    //1 3 1
    //1 4 5
    //2 3 5
    //2 5 3
    //3 4 5
    //3 5 6
    //3 6 4
    //4 6 2
    //5 6 6
    
    
  • 您还可以看一下 张长志老师的通俗易懂的数据结构和算法教程(含配套资料)课程中的 172-克鲁斯卡尔((Kruskal)算法图解小节, 巩固相关知识点