Online C Compiler
Abrir no compilador

Edição didática em português. O código e suas saídas preservam o original.

Inverter uma lista encadeada em C

Inverta ligações de uma lista simples em O(N) e libere seus nós ao terminar.

Abrir no compilador

Inverter uma lista encadeada em C
Inverta ligações de uma lista simples em O(N) e libere seus nós ao terminar.

Construa uma lista encadeada de N inteiros usando malloc. Implemente reverse_list para inverter as ligações no próprio lugar, usando prev, curr e next. Retorne a nova cabeça, imprima os valores em ordem inversa e libere todos os nós.

Não copie os dados para um array auxiliar. A inversão deve percorrer cada nó uma vez e usar uma quantidade constante de ponteiros adicionais. Verifique as alocações antes de escrever.

Entrada

Primeira linha: N. Segunda linha: N inteiros separados por espaços.

Saída

Uma linha com os valores da lista invertida, separados por espaços.

Restrições

  • 1 <= N <= 100
  • -10000 <= valor <= 10000
  • Inversão com tempo O(N) e espaço auxiliar O(1).
  • Aloque os nós com malloc e libere toda a memória.
Dicas
  • Salve curr->next antes de sobrescrever essa ligação.
  • Ao terminar, curr é NULL e prev aponta para a nova cabeça.

Código C

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

struct Node {
    int data;
    struct Node *next;
};

// Reverses singly linked list in-place and returns new head
struct Node* reverse_list(struct Node *head) {
    // TODO: Implement iterative 3-pointer reversal (prev, curr, next)
    return NULL;
}

int main(void) {
    int n;
    if (scanf("%d", &n) != 1 || n <= 0) return 1;

    struct Node *head = NULL;
    struct Node *tail = NULL;

    for (int i = 0; i < n; i++) {
        int val;
        scanf("%d", &val);
        struct Node *new_node = (struct Node *)malloc(sizeof(struct Node));
        new_node->data = val;
        new_node->next = NULL;

        if (head == NULL) {
            head = new_node;
            tail = new_node;
        } else {
            tail->next = new_node;
            tail = new_node;
        }
    }

    head = reverse_list(head);

    struct Node *curr = head;
    while (curr != NULL) {
        printf("%d%s", curr->data, (curr->next == NULL) ? "" : " ");
        struct Node *temp = curr;
        curr = curr->next;
        free(temp);
    }
    printf("\n");

    return 0;
}
Abrir no compilador
Solução e explicação

Comece com prev = NULL e curr = head. Em cada repetição salve next = curr->next, altere curr->next = prev e avance com prev = curr e curr = next.

Em uma lista 1 → 2 → 3, primeiro fica 1 → NULL, depois 2 → 1 e finalmente 3 → 2 → 1. Nunca perca o ponteiro para o trecho pendente.

Para liberar, salve novamente o próximo nó antes de free. Acessar node->next depois de liberar node é uso de memória liberada. A inversão usa espaço adicional O(1); os nós originais continuam ocupando O(N).

Código da solução

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

struct Node {
    int data;
    struct Node *next;
};

struct Node* reverse_list(struct Node *head) {
    struct Node *prev = NULL;
    struct Node *curr = head;
    struct Node *next = NULL;

    while (curr != NULL) {
        // 1. Store next node before breaking link
        next = curr->next;
        // 2. Reverse current node pointer
        curr->next = prev;
        // 3. Move prev and curr forward one step
        prev = curr;
        curr = next;
    }

    return prev; // prev is the new head of the reversed list
}

int main(void) {
    int n;
    if (scanf("%d", &n) != 1 || n <= 0) return 1;

    struct Node *head = NULL;
    struct Node *tail = NULL;

    for (int i = 0; i < n; i++) {
        int val;
        scanf("%d", &val);
        struct Node *new_node = (struct Node *)malloc(sizeof(struct Node));
        new_node->data = val;
        new_node->next = NULL;

        if (head == NULL) {
            head = new_node;
            tail = new_node;
        } else {
            tail->next = new_node;
            tail = new_node;
        }
    }

    head = reverse_list(head);

    struct Node *curr = head;
    while (curr != NULL) {
        printf("%d%s", curr->data, (curr->next == NULL) ? "" : " ");
        struct Node *temp = curr;
        curr = curr->next;
        free(temp);
    }
    printf("\n");

    return 0;
}

Perguntas frequentes

Por que o código e a saída continuam em inglês?

Palavras-chave, identificadores e textos verificados pelos testes são preservados para não alterar o programa. As explicações e os controles estão traduzidos.