Lista Encadeada Simples em C

Uma lista encadeada é implementada com um nó contendo dados e um pontiero para o próximo elemento.

typedef struct NoLista
{
    Elemento data; // Conteúdo do nó
    struct NoLista* proximo; // Ponteiro para o próximo nó

} NoLista;

Criação da Lista

A função abaixo inicializa uma lista vazia com nó cabeça.

NoLista* CriarLista(void)
{
    NoLista* cabeca = (NoLista*)calloc(1, sizeof(NoLista));
    if (!cabeca) {
        perror("Falha ao alocar memória");
        exit(EXIT_FAILURE);
    }
    cabeca->proximo = NULL;
    return cabeca;
}

Criação de Novo Nó

Função auixliar para gerar novos elementos da lista.

NoLista* CriarNodo(Elemento valor)
{
    NoLista* novo = (NoLista*)calloc(1, sizeof(NoLista));
    if (!novo) {
        perror("Memória insuficiente");
        return NULL;
    }
    novo->data = valor;
    novo->proximo = NULL;
    return novo;
}

Inserção no Início

bool InserirInicio(NoLista* cabeca, Elemento valor)
{
    NoLista* novo = CriarNodo(valor);
    if (!novo) return false;

    if (!cabeca->proximo) {
        cabeca->proximo = novo;
        return true;
    }

    novo->proximo = cabeca->proximo;
    cabeca->proximo = novo;
    return true;
}

Inserção no Final

bool InserirFim(NoLista* cabeca, Elemento valor)
{
    NoLista* novo = CriarNodo(valor);
    NoLista* atual = cabeca;

    if (!novo) return false;

    if (!cabeca->proximo) {
        cabeca->proximo = novo;
        return true;
    }

    while (atual->proximo) {
        atual = atual->proximo;
    }
    atual->proximo = novo;
    return true;
}

Inserção Condicional

bool InserirDepois(NoLista* cabeca, Elemento alvo, Elemento valor)
{
    NoLista* novo = CriarNodo(valor);
    NoLista* atual = cabeca;

    if (!novo) return false;

    if (!cabeca->proximo) {
        cabeca->proximo = novo;
        return true;
    }

    while (atual->proximo) {
        atual = atual->proximo;
        if (atual->data == alvo) {
            novo->proximo = atual->proximo;
            atual->proximo = novo;
            return true;
        }
    }
    return false;
}

Remoção do Início

bool RemoverInicio(NoLista* cabeca)
{
    if (!cabeca->proximo) {
        printf("Lista vazia\n");
        return false;
    }

    NoLista* temp = cabeca->proximo;
    cabeca->proximo = temp->proximo;
    free(temp);
    return true;
}

Remoção do Final

bool RemoverFim(NoLista* cabeca)
{
    if (!cabeca->proximo) {
        printf("Lista vazia\n");
        return false;
    }

    NoLista* anterior = cabeca;
    NoLista* atual = cabeca->proximo;

    if (!atual->proximo) {
        cabeca->proximo = NULL;
        free(atual);
        return true;
    }

    while (atual->proximo) {
        anterior = atual;
        atual = atual->proximo;
    }
    anterior->proximo = NULL;
    free(atual);
    return true;
}

Remoção Condicional

bool RemoverElemento(NoLista* cabeca, Elemento alvo)
{
    NoLista* anterior = cabeca;
    NoLista* atual = cabeca->proximo;

    if (!atual) {
        printf("Lista vazia\n");
        return false;
    }

    while (atual->proximo) {
        anterior = atual;
        atual = atual->proximo;
        if (atual->data == alvo) {
            anterior->proximo = atual->proximo;
            free(atual);
            return true;
        }
    }
    printf("Elemento não encontrado\n");
    return false;
}

Tags: C estrutura de dados lista encadeada gerenciamento de memória

Publicado em 9-23 04:52