0

In this code I want to make Kruskal's algorithm, which calculates a minimum spanning tree of a given graph. And I want to use min-heap and disjoint set at the code.

To make time complexity of O(e log n), where e is the number of edges and n is the number of vertices in the graph, I will use heap and disjoint set trees.

So the method I went with was:

  • Check the numbers of vertices and edges in the given input file and make parent array and struct edge which can include at most 10000 vertices and 50000000 edges.
  • Sort the edges by the weight in a min heap in descending order.
  • Take out edges from min heap one by one and check whether it makes cycle until min heap is empty
  • If the number of edges selected is vertices-1 (if all vertices already connected ) break the while loop and print each edges and sum of weights. If all vertices can make minimum spanning tree it prints connected and if all vertices can not make minimum spanning tree it prints disconnected.

I thought the code is well done but when I run this in putty, it is exiting with segmentation fault (core dumped)

input (example)

7
9
0 1 28
0 5 10
1 2 16
1 6 14
2 3 12
3 4 22
3 6 18
4 5 25
4 6 24

result(I want)

0 5 10
2 3 12
1 6 14
1 2 16
3 4 22
4 5 25
99
CONNECTED

I checked the edges are well stored in min-heap in descending order. But I think it has mistakes in making minimum spanning tree. These are points that I am suspicious in the code.

  1. Should I make edge minheap by dynamic allocation instead of minheap[50000000]?
  2. Should I make additional data structures apart from the array parent and struct edge.

It is the code I made! Can you give me help or advice ?

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

#define maxvertice 10000
#define maxedge 50000000
typedef struct edge { //structure to store vertices and weight
    int a, b;
    int w;
}
edge;

int n = 0; //numbers of edge in the minheap 

int parent[maxvertice] = {-1,};


//array to represent disjoint sets! parent which stores the vertice connected
//if it is not connected(independent) it's parent is -1 
edge minheap[maxedge]; //heap that sorts edges 

void insertheap(edge item, int * n); // arrange edges by the weight in descending order
edge deleteheap(int * n); //popping out from the root (in descending order)
void makeunion(int x, int y); // this make x and y combined  
int findparent(int i);


int main(int argc, char * argv[]) {
    double start, end;
    int i, nv, ne, sumofweight = 0, isitdone;
    int cnt_edge = 0;
    edge item;
    //////////////

    if (argc != 2) {
        printf("usage: ./hw3 input_filename\n");
        return 0;
    }
    FILE * fp = fopen(argv[1], "r");
    if (fp == NULL) {
        printf("The input file does not exist.\n");
        return 0;
    }
    FILE * result = fopen("hw3_result.txt", "w");
    start = (double) clock() / CLOCKS_PER_SEC;

    fscanf(fp, "%d", & nv);
    printf("to test : number of vertices : %d\n", nv);
    fscanf(fp, "%d", & ne);
    printf("to test : number of edges : %d\n", ne);

    for (i = 0; i < ne; i++) {
        int firstv, secondv, weight;
        edge newedge;
        fscanf(fp, "%d %d %d", & firstv, & secondv, & weight);
        newedge.a = firstv;
        newedge.b = secondv;
        newedge.w = weight;
        // get vertices and edge's weight from the input file and put in heap
        insertheap(newedge, & n);
    }
    /*
    for(i =0 ; i<ne; i++){
         item= deleteheap(&n); 
         printf("%d", item.w); 
    }*/

    while (minheap != NULL) { //pop out from the heap until mst is completed
        item = deleteheap( & n);
        //union at array parent 
        int par1, par2;
        par1 = findparent(item.a);
        par2 = findparent(item.b);

        if (par1 != par2) {
            makeunion(par1, par2);
            printf("%d %d %d\n", item.a, item.b, item.w);
            cnt_edge = cnt_edge + 1;
            sumofweight += item.w;
        }

        if (cnt_edge == nv - 1) break;

    }
    if (cnt_edge == nv - 1) {
        // fprintf(result, "CONNECTED");
        printf("%d\n", sumofweight);
        printf("CONNECTED");

    }
    if (cnt_edge < nv - 1) {
        // fprintf(result, "DISCONNECTED"); 
        printf("DISCONNECTED\n");
    }
    end = (((double) clock()) / CLOCKS_PER_SEC);
    fclose(fp);
    fclose(result);
    printf("output written to hw3_result.txt.\n");
    printf("running time: %1f", (end - start));
    printf(" seconds\n");

}

void makeunion(int x, int y) {
    parent[x] = y;
}

int findparent(int i) {
    for (; parent[i] >= 0; i = parent[i]);
    return i;
}

void insertheap(edge item, int * n) {
    int i;
    i = * n;
    ++( * n);
    while ((i != 0) && (item.w < minheap[i / 2].w)) {
        minheap[i] = minheap[i / 2];
        i /= 2;
    }
    minheap[i] = item;
    printf("to test : the wieght %d is inserted in :%d \n", item.w, i);
}
edge deleteheap(int * n) {
    int parent, child;
    parent = 0;
    child = 1;
    edge item, temp;
    item = minheap[0];
    temp = minheap[( * n) - 1];
    ( * n) --;
    while (child <= * n) {
        if ((child < * n) && (minheap[child].w > minheap[child + 1].w)) child++;
        if (temp.w <= minheap[child].w) break;
        minheap[parent] = minheap[child];
        parent = child;
        child *= 2;
    }
    minheap[parent] = temp;
    return item;
}
2
  • Your while (minheap!=NULL) is wrong, it can never hit that because minheap is not a pointer. Looking at your code, it might be while (n>0). Commented Nov 27, 2021 at 7:08
  • o thanks i didn't thought about it Commented Nov 27, 2021 at 7:48

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.