-2

I have started to learn about linked lists, and I have written this code.

It should be a recursive call to create a new link in a linked list in c.

But, if you’ll check the output, you’ll see it’s passing over the middle links.

I don’t know why I’m losing the middle links.

Btw, I do have a destroy function in my code, I just didn’t write it here.

I do have a different version of a working code, I don’t ask for solutions, I’m only asking why this recursive idea doesn’t work.

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

typedef struct node {
    int data;
    struct node *next;
}node;

node *create(node **head, int data)
{
    if(!*head) {
        *head = malloc(sizeof(node));
        assert(*head);
        (*head)->data = data;
        (*head)->next = NULL;
        return *head;
    }
    node *new = NULL;
    new = create(&new,data);
    (*head)->next = new;
    return *head;
}
void display(node *head)
{
    assert(head);
    node *current = head;
    do
    {
        printf("%d\t",current->data);
        current = current->next;
    }while(current);
}
int main()
{
    int count = 0, data = 0;
    node *head = NULL;

    printf("Enter list count:\n");
    
    while(count <= 0){
        scanf("%d",&count);
        if(count <= 0) printf("\nEnter a valid number:\n");
    }
    while(count){
        scanf("%d",&data);
        head = create(&head,data);
        count--;
    }
    printf("\nHere are the elements:\n");
    display(head);

    return 0;
}
  • 2
    [How to debug small programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) and [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173) – VLAZ Sep 21 '22 at 23:00
  • @VLAZ Haha, I wanted to mention the fact that I don’t know how to use a debugger, but I see it was obvious. Do you see the problem anyway? – noname delete Sep 21 '22 at 23:03
  • 2
    You're mixing two methods in a bizarre way... Either pass the address of the head pointer for the function to assign, OR store the pointer returned by the function... The way you've conflated the two methods (and layered in _recursion_ too) makes my head spin... Why write confabulated code when an LL is so very simple? (PS: replacing traversal of an LL with recursion is not a good idea...) – Fe2O3 Sep 21 '22 at 23:08
  • @Fe2O3 just for fun. I first made a working create function, and then I wanted to make a recursive version of it. What is LL? – noname delete Sep 21 '22 at 23:13
  • @VLAZ I have read the links you sent me, I have already tried to explain to the duck, write it on paper, and draw the linked list with the pointers. I still can’t fix it, and that site itself says when you cannot fix it, you have a question to ask. – noname delete Sep 21 '22 at 23:16
  • 1
    LL = Linked List – VLAZ Sep 21 '22 at 23:17
  • "I am trying to shoot myself in the foot... but it's not happening... Someone please tell me how I can shoot myself in the foot successfully..."... Sorry, no... Good luck, though... `:)` (One cannot "fix" what someone is deliberately trying to break... SO answers should be "best practice", and you seem to be asking for help achieving the opposite.) – Fe2O3 Sep 21 '22 at 23:18
  • It’s just an interesting question, I don’t know why everyone here are so serious.. every other question I write gets deleted. – noname delete Sep 21 '22 at 23:25
  • 2
    It's not being "so serious"... You say you are striving to write bad code, and asking for help to make bad code work. If your problem was attempting to write good code, but something wasn't working, you'd have 3 good answers by now. Please don't ask for help when your objective is bad code. That's your fun, not the "fun" of those who are here trying to help others.. – Fe2O3 Sep 21 '22 at 23:29
  • If the intent is to prepend the newest value to an existing linked list, `(*head)->next = new;` is wrong in the non-null `*head` case. That code should be `new->next = *head; *head = new;` That's where you're most-evidently leaking nodes. – WhozCraig Sep 21 '22 at 23:50

2 Answers2

0

As implemented create() either adds a new node to the tail or iterates to the next linked node. Logic changed to affect that. It's confusing that the first argument is called head to changed it to n. Changed main() to retain the head and made the program non-interactive for ease of testing. Recatored display to use a for() loop:

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

typedef struct node {
    int data;
    struct node *next;
} node;

node *create(node **n, int data) {
    if(!*n) {
        *n = malloc(sizeof(**n));
        assert(*n);
        (*n)->data = data;
        (*n)->next = NULL;
        return *n;
    }
    node *n2 = (*n)->next;
    (*n)->next = create(&n2, data);
    return n2;
}

void display(node *head) {
    assert(head);
    for(node *c = head; c; c = c->next) {
        printf("%d\t", c->data);
    }
}

int main() {
    node *head = NULL;
    node *tail = NULL;
    for(int i = 0; i < 10; i++) {
        tail = create(&tail, i);
        if(!head) head = tail;
    }
    display(head);
    return 0;
}

and it displays:

0       1       2       3       4       5       6       7       8       9       

If you compile your code with NDEBUG (some folks do that for production) then your code no longer has any error handling.

Allan Wind
  • 23,068
  • 5
  • 28
  • 38
-1

Thank you all for your answers. I see the problem now, after “explaining to the duck” a thousand times. In function create(), under the if() block, I assigned (*head)->next = new; without first making it point to the last link, so it’s just over write the next link in every call to the function. The solution is:

  1. Add a “current” pointer points to the head(to not lose it’s value)
  2. Iterate through the list until we find the last link,
  3. assign current->next the value of new. Here is the fixed section:
    node *new = NULL;
    new = create(&new,data);
    node *current = *head;
    while(current->next) current = current->next;
    current->next = new;
    return *head;
  • This is not a recursive solution that you asked for, rather it's an iterative one where you invoke a recursive call for the base case (that is just above). Because c doesn't have standardized support for tail calls, iterative solutions are usually preferred as they don't blow up the stack if the problem is too large. If you haven't study the answer that I provided you. – Allan Wind Sep 23 '22 at 02:13
  • @AllanWind, Maybe I don’t know how to express my question like I mean it. Any way, the final solution that I uploaded, is what I was looking for. Simply change what necessary, without touching the names. – noname delete Sep 23 '22 at 07:40