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

typedef struct Node{
    int val;
    struct Node* next;
} Node;

void add_at_end(Node* head, int val){
    Node* newNode = malloc(sizeof(Node));
    newNode -> next = NULL;

    Node* temp = head;

    if(head -> next == NULL){
        head ->val = val;
        head -> next = newNode;
    }

    else{
        while(temp -> next != NULL){
            temp = temp -> next;
        }
        temp -> next = newNode;
        temp -> val = val;
    }
}

void display(Node* l){
    while(l->next != NULL){
        printf("%d -->", l->val);
        l = l->next;
    }
    printf("End\n");
}

As I said in the question, I'm creating a useless node at the end just to specify NULL. How can I remove that feature? I know I'm doing something wrong in the add_at_end function but I'm not able to rectify it. Help would be appreciated. Thanks

EDIT:

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

typedef struct Node{
    int val;
    struct Node* next;
} Node;

typedef struct List{
    Node* head;
} List;

void add_at_end(List* l, int val){
    Node* newNode = malloc(sizeof(Node));
    newNode -> next = NULL;
    newNode -> val = val;

    Node* temp = l->head;

    if(temp == NULL){
        l->head = newNode;
    }

    else{
        while(temp->next != NULL){
            temp = temp -> next;
        }
        temp -> next = newNode;
    }

}

void display(List* l){
    Node* t = l -> head;
    while(1){
        printf("%d\n", t->val);
        if(t->next == NULL) break;
        t = t->next;
    }
}
int main(){
    List l;
    l.head = NULL;

    add_at_end(&l, 10);

    add_at_end(&l, 20);

    add_at_end(&l, 30);

    display(&l);
    return 0;
}

This is my final code.

I need help adding nodes to the middle of the list. How can I do that?

  • `creating a useless node at the end just to specify NULL`...and how is that? – Sourav Ghosh Apr 23 '15 at 11:27
  • What is happening here is that the actuall last node of the list(which has a specific val) is pointing to a node whole 'val' is undefined and its 'next' pointes to NULL. –  Apr 23 '15 at 11:34

3 Answers3

1

Your node usage is all confused. When you create a new node the value should be stored into that node and the node linked into the list. Instead what you are doing is trying to add the value into the last node and then linking in a dummy node. It's a bit convoluted so I'm not sure I've explained what you have done clearly. Here is what add_to_end should be more like:

add_to_end (Node** head, int val)
{
    Node* temp;
    Node* newNode = malloc(sizeof(Node));
    if (!newNode) { 
        /* Error */ 
    }

    newNode->val = val;
    newNode->next = NULL;

    if (!*head) {
        /* empty list. Just make new node the head */
        *head = newNode;
    } else {
        /* Find the end of the list */
        temp = *head;
        while (temp->next) {
            temp = temp->next;
        }

        /* temp is now the last node. Chain new node after it */
        temp->next = newNode;
    }
}
kaylum
  • 13,833
  • 2
  • 22
  • 31
0

Instead of a null node, you can represent the end of the list with a value of NULL, i.e. with a null pointer. The list is empty when head is NULL and the last node has node->next == NULL.

For this to work, you must be able to update the head when you add a node, because after inserting the frst node, the head will no longer be NULL. (The same goes for inserting at the front or deleting the first node.)

This chan be achieved by passing a pointer to a node pointer:

void add_at_end(Node **head, int val)
{
    Node* newNode = malloc(sizeof *newNode);

    newNode->next = NULL;
    newNode->val = val;

    while (*head) {
        head = &(*head)->next;
    }

    *head = newNode;
}

Then you call add_at_and like this:

Node *head = NULL;

add_at_end(&head, 1);
add_at_end(&head, 2);
add_at_end(&head, 3);

It is important that head is initialised to NULL. More generally, all your pointers should either be NULL or point to valid nodes.

M Oehm
  • 28,726
  • 3
  • 31
  • 42
0
#include<stdio.h>
#include<stdlib.h>

typedef struct Node{
    int val;
    struct Node* next;
} Node;

void add_at_end(Node* head, int val){
    Node* newNode = (Node *)malloc(sizeof(Node));
    newNode -> next = NULL;

if(head == NULL)
{
head = new_node;
head->val = val;
}    


    if(head -> next == NULL)
   {
        new_node ->val = val;
        head -> next = newNode;
    }

    else{
Node *temp = head;
        while(temp -> next != NULL){
            temp = temp -> next;
        }
        temp -> next = newNode;
        temp -> val = val;
    }
}

void display(Node* l){
    while(l->next != NULL){
        printf("%d -->", l->val);
        l = l->next;
    }
    printf("End\n");
}
Rndp13
  • 1,094
  • 1
  • 21
  • 35
  • First thing is you should always typecast the allocated memory to the type you want.Node* newNode = (Node *)malloc(sizeof(Node)); Secondly when the head is NULL, point the head to the new_node. – Rndp13 Apr 23 '15 at 13:24
  • 1
    There's no actual need to cast the return of malloc. Some people like to but others [argue strongly against it](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). So I wouldn't necesserily push that particular barrow. – kaylum Apr 23 '15 at 20:58