Search code examples
cpointersstackgraph-theorydoubly-linked-list

Stack push function using c, implemented using doubly linked list


I am trying to implement Hierholzer's algorithm using C. I have made a push function for a simple stack implemented using doubly linked list but the pointer always moves on to the else condition, even when the starting node is empty.

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#include<stddef.h>

typedef struct node
{
    int source;
    int num;
    struct node *l, *r;
    int done;
}node;

void push(int source, int num, struct node *head)
{
    node *n = malloc(sizeof(node));
    n->num = num;
    n->l = NULL;
    n->done = 0;
    n->source = source;

    if (*head == NULL)
    {
        head = n;
        head -> r = NULL;
    }
    else
    {
        n -> r = head;
        head->l = n;
        head = n;
    }
}

int pop(node *head)
{
    if(head == NULL)
    {
        return -1;
    }
    else
    {
        node *temp = head;
        head = head->r;
        int num = temp->num;
        free(temp);
        return num;
    }
}

void append(node *extra, node *head)
{
    node *temp = extra;
    while(temp->r != NULL)
    {
        temp = temp->r;
    }
    temp->r = head;
    head->l = temp;
    head = extra;
}

node** read(int num)
{
    char a[2000] = "Assignment1.txt" ,c[1000];


    FILE *f = fopen(a,"r");
    printf("Got file\n");

    node *adj[num];

    int i=0;
    node *l;
    printf("l: %d\n", l);

    while(fscanf(f,"%s",c))
    {

        char *p = strtok(c, ",");
        while(p!=NULL)
        {
            push(i, atoi(p), l);
            p = strtok (NULL, ",");
        }
        adj[i++] = l;
    }
    printf("Adjacency list created\n");

    return adj;
}

node* euler(node *adj[],int n, int i)
{
    node *cpath = NULL;
    node *fin = NULL;
    node *extra;
    node *temp = adj[i];
    node *tempi;

    while(temp!=NULL)
    {
        if(temp->r->r == NULL)
        {
            tempi = temp;
        }

        if(temp->done == 0)
        {
            temp->done = 1;
            push(i, temp->num, cpath);
            extra = euler(adj, n, temp->num);
            append(extra, cpath);
        }
        else
        {
            temp = temp->r;
        }
    }

    while(tempi->l != NULL)
    {
        push(i,tempi->num, fin);
        extra = euler(adj, n, tempi->num);
        append(tempi, fin);
        tempi = tempi->l;
    }
    if(tempi != NULL)
    {
        push(i,tempi->num, fin);
        extra = euler(adj, n, tempi->num);
        append(tempi, fin);
    }

    return fin;
}

int main()
{
    int n;
    printf("Enter the number of vertices: ");
    scanf("%d", &n);
    node **adj = read(n);
    node *fin = euler(adj, n, 0);
    node *temp = fin;

    while(temp!=NULL)
    {
        printf("%d ", temp->num);
        temp = temp->r;
    }

    return 0;
}

I am yet to debug the entire code but I am getting stuck at the read() function where the input is an Assignment1.txt which includes:

2,3
3,1
1,2

I am not able to understand why I am getting a segmentation fault.


Solution

  • The function deals with a copy of the value of the passed to it pointer to the head node. So the original pointer itself is not changed in the function. It is the copy of the value of the passed pointer that is changed within the function.

    You need to pass the pointer by reference that is indirectly through pointer to the pointer.

    The function can be declared and defined the following way.

    int push( struct node **head, int source, int num )
    {
        node *n = malloc(sizeof(node));
        int success = n != NULL;
    
        if ( success )
        {
            n->source = source;
            n->num    = num;
            n->done   = 0;
            
            n->l = NULL;
            n->r = *head;
            if ( *head != NULL ) ( *head )->l = n;
    
            *head = n;
        }
    
        return success;
    }