Código executável completo demonstrando implementação de Lista Encadeada e Árvore Binária de Busca (BST) com percursos e desalocação total de memória.


📄 Exemplo 1: Lista Simplesmente Encadeada Completa (lista_encadeada.c)

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

typedef struct No {
    int valor;
    struct No *prox;
} No;

No* inserirInicio(No *head, int valor) {
    No *novo = (No*)malloc(sizeof(No));
    if (novo == NULL) return head;
    novo->valor = valor;
    novo->prox = head;
    return novo;
}

void imprimirLista(const No *head) {
    printf("Head -> ");
    const No *atual = head;
    while (atual != NULL) {
        printf("[%d] -> ", atual->valor);
        atual = atual->prox;
    }
    printf("NULL\n");
}

void liberarLista(No *head) {
    No *atual = head;
    while (atual != NULL) {
        No *temp = atual->prox;
        free(atual);
        atual = temp;
    }
}

int main(void) {
    No *lista = NULL;

    printf("====================================================\n");
    printf(" 🔗 LISTA SIMPLESMENTE ENCADEADA NO HEAP\n");
    printf("====================================================\n");

    lista = inserirInicio(lista, 30);
    lista = inserirInicio(lista, 20);
    lista = inserirInicio(lista, 10);

    imprimirLista(lista);

    liberarLista(lista);
    lista = NULL;
    printf(">> Memoria da lista liberada com sucesso. Valgrind Clean! ✅\n");
    printf("====================================================\n");

    return 0;
}

📄 Exemplo 2: Árvore Binária de Busca BST (arvore_bst.c)

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

typedef struct NoBST {
    int chave;
    struct NoBST *esq;
    struct NoBST *dir;
} NoBST;

NoBST* inserir(NoBST *raiz, int chave) {
    if (raiz == NULL) {
        NoBST *novo = (NoBST*)malloc(sizeof(NoBST));
        novo->chave = chave;
        novo->esq = novo->dir = NULL;
        return novo;
    }
    if (chave < raiz->chave) raiz->esq = inserir(raiz->esq, chave);
    else if (chave > raiz->chave) raiz->dir = inserir(raiz->dir, chave);
    return raiz;
}

void percursoInOrder(const NoBST *raiz) {
    if (raiz != NULL) {
        percursoInOrder(raiz->esq);
        printf("%d ", raiz->chave);
        percursoInOrder(raiz->dir);
    }
}

void destruirArvore(NoBST *raiz) {
    if (raiz != NULL) {
        destruirArvore(raiz->esq); // Libera filho esquerdo
        destruirArvore(raiz->dir); // Libera filho direito
        free(raiz);                // Libera a raiz (Pós-ordem)
    }
}

int main(void) {
    NoBST *raiz = NULL;

    int dados[] = {50, 30, 70, 20, 40, 60, 80};
    size_t n = sizeof(dados) / sizeof(dados[0]);

    for (size_t i = 0; i < n; i++) {
        raiz = inserir(raiz, dados[i]);
    }

    printf("====================================================\n");
    printf(" 🌳 ARVORE BINARIA DE BUSCA (BST)\n");
    printf("====================================================\n");
    printf(" Percurso In-Order (Ordenado): ");
    percursoInOrder(raiz);
    printf("\n");

    destruirArvore(raiz);
    raiz = NULL;
    printf(">> Arvore BST desalocada com sucesso em Pos-Ordem! ✅\n");
    printf("====================================================\n");

    return 0;
}

🧭 Navegação Rápida

| 📖 Teoria | 📊 Slides | 🧠 Quiz | 💻 Exemplos | 🧩 Exercícios | | :— | :— | :— | :— | :— | | Ler Teoria | Ver Slides | Fazer Quiz | Ver Exemplos | Praticar Exercícios |


⬅️ Voltar ao Sumário da Especialização