-1

I have written this code in c to implement linked list. while the semantic and syntax are fine, it does not work as it should. For example, when I insert 1 into the list and then print the linked list, it shows that the list is empty.

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

struct node {
    int info;
    struct node *next;
}; typedef struct node Node;


void addNode(Node *head, int x)
{
        Node *temp;
        temp=malloc(sizeof(temp));
        temp->info=x;
        if (head==NULL)//if this is the first node in the list
        {
            head=temp;
            temp->next=NULL;

        }
        else //if not, add it as the head
        {
            temp->next=head;
            head=temp;
        }
}

void appendNode(Node *head, int x)
{
    Node *rear =head;
    Node *temp= malloc(sizeof(temp));
    temp->info=x;
    temp->next=NULL;
    while (rear->next!=NULL)
        rear=rear->next;
    rear->next=temp;
    rear=temp;

}

void insertNodeafter(Node *head, int location, int x)
{
    int i;
    Node *before, *after = head;
    Node *temp= malloc(sizeof(temp));
    temp->info=x;

    for (i=0;i<location;i++)
        before=before->next;
    after=before->next;
    temp->next=after;
    before->next=temp;

}

void insert(Node *head, int x)
{
    int c=0;
    Node *temp;
    temp=head;
    if(temp==NULL)
    {
    addNode(temp,x);
    }
    else
    {
    while(temp!=NULL)
    {
        if(temp->info<x)
        c++;
        temp=temp->next;
    }
    if(c==0)
        addNode(temp,x);
    else if(c<listSize())
        insertNodeafter(temp,x,++c);
    else
        appendNode(temp,x);
    }
}

int listSize()
{
    Node *head, *n;
    int c=0;
    n=head;
    while(n!=NULL)
    {
    n=n->next;
    c++;
    }
    return c;
}

void DisplayLinkedList(Node* head)
{
    Node *rear=NULL;
    if (head==NULL)
        printf("list is empty!\n");
    else
    {
        rear=head;
        while (rear!=NULL)
            printf("%d |---> ", rear->info);
            rear=rear->next;
    }


}

int getNextNode(Node *head)
{
    if (head == NULL)
        return -1;
    else
        return head->next->info;
}

Node* deleteNode(Node *head, int x)
{
    Node *temp;
    if (head == NULL)
        return NULL;

    else
        {
            if (head->info==x)
                {
                temp = head->next;
                free(head);
                head=temp;
                return head;
                }
            else
                {
                deleteNode(head->next,x);
                return head;
                }
        }
}

void main()
{
    int i=0;
    Node *myNode;
    insert(myNode,1);
    DisplayLinkedList(myNode); 

}
  • Usually a debugger is very helpful in similar cases. – Eugene Sh. Jun 27 '17 at 16:30
  • myNode in main should be allocated with new memory. And field next should be pointed to NULL. – mattn Jun 27 '17 at 16:31
  • Even after making changes as specified by mattn value of `myNode` will not be modified in the function. To modify it either pass `&myNode` (and accordingly change functions) or make it global. – GAURANG VYAS Jun 27 '17 at 16:32
  • 2
    1) _A function may change the values of its parameters, but these changes cannot affect the values of the arguments._ – BLUEPIXY Jun 27 '17 at 16:35
  • 3
    Also, `malloc(sizeof(*temp));` The asterisk matters. – Sinan Ünür Jun 27 '17 at 17:02
  • 1
    have you tried debugging the code? Fundamental thing is when we pass value from one function to other it should be done by call by reference if we want the actual and formal parameters to contain the same value. Try with passing Node ** instead of Node *. The assigned memory will only be then available to the calling function. – LinuxStuff Jun 27 '17 at 17:27
  • Give a look at [this](https://stackoverflow.com/questions/2229498/passing-by-reference-in-c) question regarding C as a Pass-by-reference language – DarkCygnus Jun 27 '17 at 17:56

2 Answers2

1

Because you are using Node* variable instead of using Node** variable in function parameter. Since you are using Node* so changes done in variable head is local to that function. If you want to reflect these changes even after function call(which you obviously wants to) then use Node** and use it accordingly in your code.

GAURANG VYAS
  • 689
  • 5
  • 16
cse
  • 4,066
  • 2
  • 20
  • 37
-1

As the previous poster has mentioned, it is best to use Node** variable to reflect changes after a function call. If you wanted to use Node*, you'd have to return Node* back to main to print from it.

I pared your code down to add the 1, using AddNode, insert and DisplayLinkedList and it is now displaying correctly with the code below.

You should also set Node* to NULL in main to initialize the empty linked list. Check your DisplayLinkedList function - you're missing curly brackets in the while loop. It was only reading the printf line and not traversing the list, leading to an infinite loop.

Best practice is to debug and test as you are creating this program.

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

void main()
{
    int i=0;
    Node *myNode;
    myNode = NULL;
    insert(&myNode,1);
    DisplayLinkedList(myNode);
}

void addNode(Node **head, int x)
{
    Node *temp;
        temp=malloc(sizeof(temp));
        temp->info=x;
        if (*head==NULL)//if this is the first node in the list
        {
            *head=temp;
            temp->next = NULL;
        }
        else //if not, add it as the head
        {
            temp->next=*head;
            *head=temp;
        }
}

void insert(Node **head, int x)
{
    int c=0;
    Node *temp;
    temp=*head;
    if(temp==NULL)
    {
        addNode(head ,x);
    }
}

void DisplayLinkedList(Node* head)
{
    Node *rear=NULL;
    if (head==NULL)
        printf("list is empty!\n");
    else
    {
        rear=head;
        while (rear!=NULL)
    {
            printf("%d |---> ", rear->info);
            rear=rear->next;
    }
    }
}
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339