#include <iostream>
#include <cstdio>

struct linked_list
{
    int val;
    struct linked_list *next;
};

using namespace std;

int release_list(struct linked_list* head)
{
    struct linked_list *cur = head;
    while(cur != nullptr)
    {
        struct linked_list *next = cur->next;
        delete cur;
        cur = next;
    }
    return 0;
}

void gen_list(const int gen_count, struct linked_list** head)
{
    struct linked_list **cur = head;
    for(int i = 0; i < gen_count; i++)
    {
        (*cur) = (struct linked_list*)calloc(sizeof(struct linked_list), 1);
        (*cur)->next = nullptr;
        (*cur)->val = i;
        cur = &((*cur)->next);
    }
}

void show_list(struct linked_list *head)
{
    struct linked_list *cur = head;
    while(cur != nullptr)
    {
        printf("%d -> ", cur->val);
        cur = cur->next;
    }
    printf("\n");
}

void del_node(int val, struct linked_list **head)
{
    struct linked_list **curr = head; // We need a pointer to "a pointer to a linked-list"
    while((*curr)->val != val)        // Dereference the pointer and compare the value, if value is we want to delete, the loop will stop.
    {
        curr = &((*curr)->next);      // Walk to the next node, so we record the pointer to "a pointer to a linked-list"
        if((*curr) == nullptr)        // If we walk to the end, return.
            return;
    }
    struct linked_list *delptr = *curr;  // record the pointer we need to delete.
    *curr = (*curr)->next;               // point the current "next pointer" to next pointer.
    delete(delptr);                      // and delete it!
}

int main()
{
    struct linked_list *list_node = nullptr;
    gen_list(10, &list_node);
    show_list(list_node);
    for(int i = 0; i < 5; i++)
    {
        del_node(i, &list_node);
        show_list(list_node);
    }
    printf("Cleaning...\n");
    release_list(list_node);
    return 0;
}
