struct Nodo {
int Elemento; struct Nodo *Prox; };
typedef struct Nodo *PNodo;
Copiar para o ficheiro “ListasLigadasSimples.h” e adaptar as funções associadas às seguintes operações: Criar; CriarNodo; LibertarNodo; Vazia; Listar, ListarRec, ListarContrarioRec; InserirInicio.
1) Implementar uma função para preencher uma lista ligada L com valores inteiros positivos, inseridos a partir do teclado.
PNodo ConstruirLista () { PNodo L;
int X; L = Criar();
printf(“Inserir um inteiro positivo (negativo para terminar): \n”); scanf(“%d”, &X);
while (X >= 0) {
L = InserirInicio(L, X);
printf(“Inserir um inteiro positivo (negativo para terminar): \n”); scanf(“%d”, &X); } return L; } #include <stdio.h> #include <stdlib.h>
#include “ListasLigadasSimples.h” // deve estar na diretoria/pasta do main main () {
PNodo Lista;
Lista = ConstruirLista();
printf(“Listar do início para o fim:\n “); ListarRec(Lista);
printf(“\nListar do fim para o início:\n”); ListarContrarioRec(Lista);
printf(“\n”); }
2) Implementar uma função para determinar a soma dos elementos duma lista ligada L com valores inteiros positivos.
// versão iterativa
int SomaLista (PNodo L) { int soma = 0;
PNodo P = L; while (P != NULL) {
soma = soma + P->Elemento; P = P->Prox;
}
return soma; }
// versão recursiva
int SomaListaRec (PNodo L) { if (L == NULL)
return 0;
return P->Elemento + SomaListaRec(L->Prox); }
// acrescentar ao main anterior … main () { int S; … S = SomaLista(Lista); // S = SomaListaRec(Lista); printf(“Soma = %d\n”, S); }
3) Implementar uma função para determinar a quantidade de elementos duma lista ligada L com valores inteiros positivos maiores ou iguais a um valor K.
// versão iterativa
int NumMaioresIguaisK (PNodo L, int K) { int cont = 0; PNodo P = L; while (P != NULL) { if (P->Elemento >= K) cont++; P = P->Prox;
// versão recursiva
int NumMaiorIguaisKRec (PNodo L, int K) { if (L == NULL) return 0; if (P->Elemento >= K) return 1 + NumMaiorIguaisKRec(L->Prox, K); else return NumMaiorIguaisKRec(L->Prox, K); }
// acrescentar ao main anterior …
main () {
int S, N, K; …
printf(“Insira um valor inteiro positivo:\n”); scanf(“%d”, &K);
N = NumeroMaioresIguaisK(Lista, K);
printf(“Numero de elementos maiores ou iguais a %d = %d\n”, K, S); }
Acrescentar ao ficheiro “ListasLigadasSimples.h” e adaptar as funções associadas às seguintes operações: Consultar, ConsultarRec; ProcurarAnterior, ProcurarAnteriorRec; Remove, RemoverRec.
4) Implementar uma função que, dados uma lista ligada L com valores interios positivos e um inteiro X, remova um elemento da lista L com valor igual a X, caso exista.
PNodo RemoverIgual (PNodo L, int X) {
if (ConsultarRec(L, X) == 0) // X não está em L return L;
L = Remover(L, X); return L;
}
5) Implementar uma função que, dados uma lista ligada L com valores interios positivos e um inteiro X, remova todos os elementos da lista L com valores iguais a X, se existem.
// Versão 1: usar as funções já existentes PNodo RemoverIguais (PNodo L, int X) {
while (ConsultarRec(L, X) == 1) // X está em L L = Remover(L, X);
return L; }
Acrescentar ao main.
// Versão 2: sem usar as funções existentes PNodo RemoverIguais (PNodo L, int X) {
PNodo P, PAnt;
while (L != NULL && L->Elemento == X) { // remover todos os nodos P = L;
L = L->Prox; // com X do início da lista P = LibertarNodo(P);
}
if (L == NULL) // a lista L ficou vazia com a retirada dos nodos
return L; // com X
// L não está vazia e o seu 1º elemento é diferente de X PAnt = L; // PAnt aponta sempre para um nodo sem X P = L->Prox;
while (P != NULL) {
if (P->Elemento == X) { // remover este nodo PAnt->Prox = P->Prox; // manter PAnt igual P = LibertarNodo(P);
P = PAnt->Prox; // P aponta para o prox de PAnt } else { PAnt = P; P = P->Prox; } }
6) Implementar uma função que, dados uma lista ligada L com valores inteiros positivos e um número inteiro positivo N, remova da lista L os seus N primeiros elementos e retorne a lista resultante. Caso N seja maior do que o comprimento da lista, todos os seus elementos devem ser removidos e o resultado deve ser uma lista vazia.
PNodo RemoverNPrimeiros (PNodo L, int N) { int i, k;
k = Tamanho(L);
if (N > K) // remover os k primeiros elementos de L, N = k; // tal que N = min { N, Tamanho(L) } for (i = 1; i <= N; i++)
L = Remover(L, L->Elemento); return L;
}
Acrescentar ao main.
6') Implementar uma função que, dados uma lista ligada L com valores inteiros positivos e um número inteiro positivo N, remova da lista L os seus N últimos elementos e retorne a lista resultante. Caso N seja maior do que o comprimento da lista, todos os seus elementos devem ser removidos e o resultado deve ser uma lista vazia.
PNodo RemoverNUltimos (PNodo L, int N) { int i, k;
PNodo P = L, L2; k = Tamanho(L);
if (N >= k) { // remover todos os elementos de L, for (i = 1; i <= k; i++) L = Remover(L, L->Elemento); return L; } for (i = 1; i < k-N; i++) P = P->Prox; L2 = P->Prox; P->Prox = NULL; for (i = 1; i < k-N; i++) L2 = Remover(L2, L2->Elemento); return L; } Acrescentar ao main.
7) Implementar uma função que receba como parâmetro uma lista L de valores inteiros positivos e um número inteiro positivo M e divida a lista em duas, de tal forma que a segunda lista comece com o elemento logo após o elemento com valor igual a M.
Comentários: a 1ª lista fica compelo menos um elemento (o M) e a 2ª pode ficar vazia (M é o último nodo da lista L); logo, L fica a apontar para a 1ª lista, pelo que não é necessário devolver L. Basta devolver L2, que é o ponteiro para a 2ª lista.
PNodo DividirLista (PNodo L, int M) { PNodo L2, P = L;
while (P != NULL && P->Elemento != M) // se “P == NULL”, então P = P->Prox; // já não testa “P->Elemento != M” if (P == NULL) // a 1ª lista é toda a lista L
L2 = NULL; // a 2ª lista é vazia
else { // P aponta para M, que será o último elemento da 1ª lista L2 = P->Prox; // L2 pode ser vazia, se P->Prox == NULL P->Prox = NULL; // P aponta para o último nodo da 1ª lista }
return L2; }
ou
PNodo DividirLista (PNodo L, int M) { PNodo L2 = NULL, P = L;
if (ConsultarRec(L, M) == 0) return L2;
while (P->Elemento != M) // M está em L P = P->Prox;
L2 = P->Prox; // L2 pode ser vazia, se P->Prox == NULL P->Prox = NULL; // P aponta para o último nodo da 1ª lista return L2;
}
8) Implementar uma função que determine o maior valor associado a um elemento de uma lista ligada L com valores inteiros positivos.
Comentários: assumir-se que a lista é não vazia. int MaiorElemento (PNodo L) {
int maior = L->Elemento; // maior = 1º elemento de L
PNodo P = L->Prox; // P aponta para o 2º elemento de L while (P != NULL) { if (P->Elemento > maior) maior = P->Elemento; P = P->Prox; } return maior; } Acrescentar ao main.
9) Implementar uma função que remova todos os elementos de uma lista ligada L com valores inteiros positivos, cujos elementos sejam iguais ao maior valor da lista L (usar a função implementada no exercício anterior).
// Versão 1
PNodo RemoverIguaisMaior (PNodo L) {
int maior = MaiorElemento(L); // usando a função construída em 8 while (ConsultarRec(L, maior) == 1) // maior está em L
L = Remover(L, maior); return L;
}
Acrescentar ao main.
// Versão 2
PNodo RemoverIguaisMaior (PNodo L) {
int maior = MaiorElemento(L); // usando a função construída em 8 L = RemoverIguais(L, maior); // usando a função construída em 5 return L;
}