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

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


// Поиск узла по значению.
// Возвращает найденный узел, а через prev записывает предыдущий.
Node *find_node(Node *head, int value, Node **prev){
    Node *current = head;
    *prev = NULL;
    while (current != NULL) {
        if (current->value == value) {
            return current;
        }
        *prev = current;
        current = current->next;
    }
    return NULL;
}

// Удаление узла из односвязного списка.
void remove_node(Node **head, Node *node, Node *prev){
    if (node == NULL) {
        return;
    }
    if (prev == NULL) {
        // Удаляем первый узел
        *head = node->next;
    } else {
        // Перепрыгиваем через удаляемый узел
        prev->next = node->next;
    }
    free(node);
}

int main(void){
    Node *head = malloc(sizeof(Node));
    Node *second = malloc(sizeof(Node));
    Node *third = malloc(sizeof(Node));

    head->value = 10;
    head->next = second;

    second->value = 20;
    second->next = third;

    third->value = 30;
    third->next = NULL;

    // Создаём новый узел
    Node *new_node = malloc(sizeof(Node));
    new_node->value = 25;
    // Вставляем его между second и third
    new_node->next = second->next;
    second->next = new_node;

    // Удаление из середины
    //   находим узел 20
    Node *prev = NULL;
    Node *node = find_node(head, 20, &prev);
    //   удаляем найденный узел
    if (node != NULL) {
        remove_node(&head, node, prev);
    }

    // Проходим по списку
    Node *current = head;
    while (current != NULL) {
        printf("%d\n", current->value);// 10 25 30
        current = current->next;
    }

    // Освобождаем оставшиеся узлы
    current = head;
    while (current != NULL) {
        Node *next = current->next;
        free(current);
        current = next;
    }

    return 0;
}