Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于C语言的Kruskals算法_C_Algorithm - Fatal编程技术网

基于C语言的Kruskals算法

基于C语言的Kruskals算法,c,algorithm,C,Algorithm,我有两个Kruskal算法实现。一个是我做的,另一个是我从朋友那里拿走的。这两个程序在我看来几乎一样,除了一些无关紧要的事情 他的程序给出的输出与我的不同,尽管我认为他们都给出了错误的边集,但权重正确 我的节目: #include<stdio.h> #include<stdlib.h> typedef struct info { int initial; int final; int weight; }info; void uon(int x,

我有两个Kruskal算法实现。一个是我做的,另一个是我从朋友那里拿走的。这两个程序在我看来几乎一样,除了一些无关紧要的事情

他的程序给出的输出与我的不同,尽管我认为他们都给出了错误的边集,但权重正确

我的节目:

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

typedef struct info
{
    int initial;
    int final;
    int weight;
}info;

void uon(int x,int y,int*p,int *r);
int findset(int x,int *p);
void sort(info *edgelist,int n);
void qksort(info *edgelist,int l,int u);
int partition(info *edgelist,int l,int u);
void makeset(int n,int *p,int *r);
int kruskal(info *edgelist,int n,int w);

int main()
{

    FILE *fp;
    int n,i,j,temp;
    int **gmatrix,cost;
    info *edgelist;
    int cnt =0,a;
    fp = fopen("grph.txt","r");

    fscanf(fp,"%d",&n);

    gmatrix=(int**)calloc(sizeof(int*),n);

    for(i=0;i<n;i++)
        gmatrix[i]=(int*)calloc(sizeof(int),n);

    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            fscanf(fp,"%d",&temp);
            gmatrix[i][j]=temp;
        }
    }

    edgelist = (info*)calloc(sizeof(info),n*n);

    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            printf("%d  ",gmatrix[i][j]);
            temp = gmatrix[i][j];
            a=cnt;
            if(temp !=0)
            {
                edgelist[a].initial = i;
                edgelist[a].weight = temp;
                edgelist[a].final = j;
                cnt++;
            }

        }
        printf("\n");
    }
    printf("%d \n",edgelist[0].initial);
    printf("%d \n ",cnt);

    cost =kruskal(edgelist,n,cnt);
    printf("\nTotal Cost is %d",cost);

    return 0;
}

int kruskal(info *edgelist,int n,int cnt)
{
    int b,i,initial,dest,cost_cnt=0;
    int *p,*r;
    int cost=0;
    info *krus;

    p = (int*)calloc(sizeof(int),n);
    r = (int*)calloc(sizeof(int),n);

    makeset(n,p,r);
    qksort(edgelist,0,cnt);
    //sort(edgelist,w);

    krus=(info*)calloc(sizeof(info),n-1);
    for(i=0;i<cnt;i++)
    {
        //printf("INITIAL 1 : %d \n",edgelist[i].initial);
        initial=findset(edgelist[i].initial,p);
    //  printf("INITIAL 2 : %d \n",initial);
        dest=findset(edgelist[i].final,p);

        if(initial!=dest)
        {
            b=cost_cnt; 
            krus[b].initial=initial;
            krus[b].final=dest;
            krus[b].weight=edgelist[i].weight;
            cost_cnt++;
            uon(initial,dest,p,r);
        }

    }
        for(i=0;i<cost_cnt;i++)
        {
            printf("{%d,%d}: %d \n",krus[i].initial+1,krus[i].final+1, krus[i].weight);
            cost = cost + krus[i].weight;
        }
    return cost;

}

void uon(int initial,int dest,int *p,int *r)
{
    int u,v;
    //link(findset(x),findset(y));
    printf("\n X1 : %d",initial);
    u = findset(initial,p);
    printf("\n X2 : %d",initial);
    v = findset(dest,p);
    if(r[u]>r[v])
    {
        p[v] = u;
    }
    else
    {
        p[u] = v;

        if(r[u]==r[v])
            r[v] = r[v]+1;
    }
}


int findset(int x,int *p)
{
    if(x!=p[x])
    {

        p[x]=findset(p[x],p);
    }
    return p[x];
}
void makeset(int n,int *p,int *r)
{
    int i;
    for(i=0;i<n;i++)
    {
        p[i] = i;
        r[i] = 0;
    }
}



void qksort(info *edgelist,int l,int u) {
    int pq;
    if(l<u) 
    {
        pq=partition(edgelist,l,u);
        qksort(edgelist,l,pq-1);
        qksort(edgelist,pq+1,u);
    }
}

int partition(info *edgelist,int l,int u) {
    int i,j,pq;
    info pv,t;
    pv.initial=edgelist[l].initial;
    pv.final=edgelist[l].final;
    pv.weight=edgelist[l].weight;
    j=l;
    for(i=l+1;i<=u;i++)
    {
        if(edgelist[i].weight<=pv.weight) 
        {
            j++;
            t=edgelist[i];

            t.initial=edgelist[i].initial;
            t.final=edgelist[i].final;
            t.weight=edgelist[i].weight;

            edgelist[i].initial=edgelist[j].initial;
            edgelist[i].final=edgelist[j].final;
            edgelist[i].weight=edgelist[j].weight;

            edgelist[j].initial=t.initial;
            edgelist[j].final=t.final;
            edgelist[j].weight=t.weight;
        }
    }
    pq=j;

    t.initial=edgelist[pq].initial;
    t.final=edgelist[pq].final;
    t.weight=edgelist[pq].weight;

    edgelist[pq].initial=edgelist[l].initial;
    edgelist[pq].final=edgelist[l].final;
    edgelist[pq].weight=edgelist[l].weight;

    edgelist[l].initial=t.initial;
    edgelist[l].final=t.final;
    edgelist[l].weight=t.weight;

    return(pq);
}
权重为37,但程序没有给出正确的边集。

排序顺序 代码之间的区别在于,在快速分拣例行程序中,一个代码使用:

if(edgelist[i].weight<=pv.weight) 
它在通过findset例程后存储初始变量和dest变量。这应替换为:

krus[b].initial=edgelist[i].initial
krus[b].final=edgelist[i].final
附笔。 顺便说一句,这两种解决方案都有调用的缺陷

 qksort(edgelist,0,cnt);
而不是

 qksort(edgelist,0,cnt-1);

但这对输出没有任何影响。(所发生的一切是,第一条显示的边看起来像是从0开始和结束,因此被忽略。)

显然,打印的权重与节点编号不对应,因此如果解析和打印正常,则节点信息在某个地方损坏

快速排序实现似乎很好,修改节点信息的唯一其他地方是
kruskal()
函数


因此,提示:再次检查分配给
krus[b]。initial
initial
真的是edge
i
的初始节点号吗?

这是您发布的大量代码,不太可能有很多用户会通读这些代码。到目前为止,您发现了哪些差异?哪些是重要的?哪些没有?这肯定是很多代码。引起我注意的一件事(可能不是唯一的问题,甚至不是主要问题)是
calloc
的使用不一致:第一个参数应该是元素的数量,最后一个是元素的大小。这可能会影响内存的分配和清空方式。通常,这些错误的存在表明代码中还有其他不一致之处。Kruskals算法是一个众所周知的问题。我建议您找到一个已经实现的算法版本并使用它。你要求代码检查,这属于寻找一个更简单的输入图,也会导致你的问题。然后调试代码,看看哪里出错了。如果有必要,先在纸上做算法——或者使用。显然,至少有一件事“无关紧要”。。。谢谢你的回答。我反复查看了算法和程序,发现在为解图赋值时也在考虑同样的问题。这似乎不对。你在这里说的话证实了这一点。谢谢:)
krus[b].initial=initial;
krus[b].final=dest;
krus[b].initial=edgelist[i].initial
krus[b].final=edgelist[i].final
 qksort(edgelist,0,cnt);
 qksort(edgelist,0,cnt-1);