Lista Encadeada¶
Usando como base essa implementação, crie as operações propostas a seguir:
#include <stdio.h>
#include <stdlib.h>
typedef struct no {
int valor;
struct no* proximo;
} No;
typedef struct lista {
No* inicio;
} Lista;
Lista* cria_lista() {
Lista* self = malloc(sizeof(Lista));
self->inicio = NULL;
return self;
}
No* cria_no(int valor, No* proximo) {
No* self = malloc(sizeof(No));
self->valor = valor;
self->proximo = proximo;
return self;
}
void inserir_inicio(Lista* lista, int valor) {
No* novo_no = cria_no(valor, lista->inicio);
lista->inicio = novo_no;
}
void inserir_final(Lista* lista, int valor) {
No* novo_no = cria_no(valor, NULL);
if (lista->inicio == NULL) {
lista->inicio = novo_no;
} else {
No* iter = lista->inicio;
while (iter->proximo != NULL) {
iter = iter->proximo;
}
iter->proximo = novo_no;
}
}
int tamanho(Lista* lista) {
int count = 0;
No* iter = lista->inicio;
while (iter != NULL) {
count++;
iter = iter->proximo;
}
return count;
}
void imprime(Lista* lista) {
No* iter = lista->inicio;
while (iter != NULL) {
printf("%d ", iter->valor);
iter = iter->proximo;
}
printf("\n");
}
int elemento(Lista* lista, int pos) {
No* iter = lista->inicio;
int i = 0;
while (iter != NULL && i < pos) {
iter = iter->proximo;
i++;
}
if (iter == NULL) {
printf("Posição inválida!\n");
return -1;
}
return iter->valor;
}
int main() {
Lista* lista1 = cria_lista();
inserir_final(lista1, 10);
inserir_final(lista1, 20);
inserir_final(lista1, 30);
imprime(lista1);
inserir_inicio(lista1, 5);
imprime(lista1);
printf("Tamanho: %d\n", tamanho(lista1));
printf("Elemento na posição 2: %d\n", elemento(lista1, 2));
return 0;
}
📚 Lista de Exercícios – Lista Encadeada Dinâmica¶
Nível 1 – Operações básicas¶
- Função
vazia(Lista* l)- Retorna
1se a lista estiver vazia,0caso contrário.
- Retorna
- Função
remover_inicio(Lista* l)- Remove o primeiro nó da lista.
- Lembre-se de liberar a memória com
free().
- Função
remover_final(Lista* l)- Remove o último nó da lista.
- Cuide dos casos com apenas um elemento.
- Função
buscar(Lista* l, int valor)- Retorna a posição do primeiro nó com o valor procurado, ou
-1se não existir.
- Retorna a posição do primeiro nó com o valor procurado, ou
Nível 2 – Inserções e remoções intermediárias¶
- Função
inserir_pos(Lista* l, int valor, int pos)- Insere um novo nó na posição indicada (0 = início).
- Se
posfor maior que o tamanho, insira no final.
- Função
remover_pos(Lista* l, int pos)- Remove o nó na posição indicada.
- Cuide dos casos de lista vazia e posição inválida.
- Função
remover_valor(Lista* l, int valor)- Remove a primeira ocorrência de um valor na lista.
- Função
remover_todos(Lista* l, int valor)- Remove todas as ocorrências de um determinado valor.
Nível 3 – Manipulações avançadas¶
- Função
inverter(Lista* l)- Inverta a ordem dos nós da lista (pode ser iterativa ou recursiva).
- Exemplo:
10 → 20 → 30→30 → 20 → 10.
- Função
copiar(Lista* origem)- Retorne uma nova lista com os mesmos valores da lista original.
- Função
concatenar(Lista* l1, Lista* l2)- Acrescente todos os nós de
l2ao final del1.
- Acrescente todos os nós de
- Função
ordenar(Lista* l)- Ordene a lista em ordem crescente (use bubble sort ou insertion sort adaptado para listas encadeadas).
Nível 4 – Desafios opcionais¶
- Função
maior_elemento(Lista* l)- Retorne o maior valor armazenado.
- Função
menor_elemento(Lista* l)- Retorne o menor valor armazenado.
- Função
iguais(Lista* l1, Lista* l2)- Retorna
1se ambas têm o mesmo tamanho e os mesmos valores, senão0.
- Retorna
- Função
destruir_lista(Lista* l)- Libere a memória de todos os nós e também da estrutura
Lista.
- Libere a memória de todos os nós e também da estrutura
- Função
intercalar(Lista* l1, Lista* l2)- Crie uma nova lista intercalando os elementos de
l1el2.
- Crie uma nova lista intercalando os elementos de
Dica para os alunos¶
Sempre desenhem o encadeamento dos nós no papel antes de codar — ajuda muito! Usem printf() e imprime(lista) após cada operação para conferir se a estrutura ainda está consistente. Cuidem para não perder referências aos nós (evita vazamento de memória).