Vous êtes sur la page 1sur 10

Atividade de laboratrio listas encadeadas simples

1. Estrutura bsica
Uma lista encadeada simples uma estrutura de dados composta de uma seqncia de estruturas elementares chamadas ns. Cada n contm a) uma informao til (um dado) e b) a localizao na memria do prximo n na seqncia. Naturalmente, a informao da localizao do prximo n deve ser guardada em um ponteiro. Assim, cada n deve ser uma struct que contenha estes dois campos a) e b). Vamos dar exemplos de tais structs, variando o tipo de informao contida nos ns: 1. A informao um nmero inteiro. Neste caso, podemos escrever a struct como
struct no { int info; struct no *prox; };

A informao guardada no campo info, que um int, e a localizao do prximo n guardada no campo prox, que um ponteiro. Este ponteiro deve ser do tipo struct no, j que vai apontar para o prximo n. 2. A informao uma string:
struct no { char info[80]; struct no *prox; };

Neste caso, o campo info uma string de 80 caracteres. 3. A informao consiste de vrios dados, por exemplo nome e nmero de alunos:
struct no { char nome[80]; int ra; struct no *prox; };

Neste caso, a informao guardada em cada n consiste do conjunto da string nome e do inteiro ra. Alm da definio da struct no, definiremos tambm um tipo para o ponteiro que aponta para um n como pno
typedef struct no * pno;

Vamos representar por meio de um diagrama o primeiro caso. No diagrama abaixo est representada uma estrutura elementar e uma lista encadeada cujos dois primeiros elementos so 7 e 5 e o ltimo 9. O acesso ao primeiro elemento da lista feito atravs do ponteiro inicial. O ltimo elemento marcado por seu ponteiro prox ter o valor invlido NULL, ao invs de apontar para um prximo elemento:

2. Adio de elementos lista


Uma lista tem duas operaes fundamentais: adio de um elemento no comeo da lista e remoo do primeiro elemento da lista. O diagrama abaixo mostra os passos para a insero de um elemento da lista:

3. Exerccios adio de ns a uma lista.


1. Digite o programa a seguir que cria uma lista com um nico elemento e a imprime:
#include <stdio.h> #include <stdlib.h>

struct no { int info; struct no *prox; };

typedef struct no * pno;

int main() { /* Chamamos o ponteiro inicial de lista */ /* inicializamos com NULL, o que significa que a lista vazia */ pno lista = NULL;

pno n; /* usado para alocar um novo n */ pno p; /* usado para imprimir a lista */

/* Um novo n criado e sua info definida */ n = malloc(sizeof(struct no)); n->info = 10;

/* O n adicionado lista */ n->prox = lista; lista = n;

/* A lista imprimida */ printf("Imprimindo lista:\n"); p = lista; /* comeamos com o elemento inicial */ while(p != NULL) { printf("%d ", p->info); /* imprimimos a info de cada elemento */ p = p->prox; /* avanamos para o prximo elemento da lista */ } printf("\n");

system("pause"); return 0; }

2. Repita na main() apenas a parte de criao de um novo n e de adio lista para que sejam inseridos os valores 20 e 30. 3. No programa resultante da questo 2, isole a criao de um novo n dentro de uma funo chamada get_node(). A funo deve ser chamada assim: n = get_node(10). Esta chamada cria um novo n cujo info 10 e retorna um ponteiro para a localizao deste n. Isole tambm a adio de um novo n dentro de uma funo chamada push(). Esta funo deve ser chamada assim: push(&lista, 10); para inserir o nmero 10 no incio da lista (note que o argumento lista passado por referncia). Dica: os prottipos das funes devem ser:
pno get_node(int); void push(pno *, int);

A funo push () deve chamar a funo get_node() e a funo main() dever apenas chamar a funo push(). 4. Isole a impresso da lista em uma funo chamada print_list() que deve ser chamada assim: print_list(lista); 5. Exerccio resolvido: modifique a estrutura de dados para que a informao de cada n seja um float. Escreva um programa que l nmeros digitados pelo usurio em qualquer quantidade, usando um lao (em cada lao, o programa deve perguntar se mais um nmero deve ser inserido). Dica: o lao deve ter uma forma assim:
do { /* inserir aqui a entrada de dados na lista */ printf("Mais um numero? (s/n): "); scanf(" %c", &c); /* ateno, o espao antes do %c importante */ } while(c != 'n');

Crie duas funes, uma que calcula a mdia e outra que calcula o desvio padro dos valores da lista. Estas funes devem ser usadas assim:
m = media(lista); s = desvio_padrao(lista, media); printf("media = %f, desvio padrao = %f\n", m, s);

Dica: estas duas funes percorrem toda a lista, at o final, e portanto so parecidas com a print_list(). No final, o programa deve imprimir a lista de valores digitados, sua mdia e seu desvio padro. Soluo: veja no final.

4. Remoo de elementos de uma lista


A operao fundamental de remoo de um elemento do incio da lista esquematizada no diagrama abaixo:

Usando as funes definidas nos exerccios 3 e 4, podemos escrever um exemplo em que se retira o primeiro elemento de uma lista:
main() { /* Ponteiro inicial da lista, inicialmente vazia: */ pno lista = NULL;

/* Ser usado para guardar o endereo do primeiro elemento da lista */ pno p;

/* Trs elementos so inseridos: */ push(&lista, 10); push(&lista, 20); push(&lista, 30);

/* A lista imprimida: */ print_list(lista);

/* Remoo do primeiro elemento ------------------------------*/ /* guarda a localizao do primeiro elemento: */ p = lista; /* imprime o primeiro elemento: */ printf("Removendo o elemento %d.\n", p->info); /* faz com que o ponteiro inicial aponte para o segundo elemento: */ lista = p->prox; /* devolve a memria ocupada pelo primeiro elemento: */ free(p);

/* A lista novamente imprimida: */ print_list(lista); }

5. Exerccios remoo de elementos


6. Faa o exemplo de remoo acima funcionar. Dica: parta do cdigo resultante do exerccio 4, onde j esto definidas todas as funes necessrias. 7. Exerccio resolvido: no cdigo do exerccio 6, isole a retirada do primeiro elemento em uma funo chamada pop(). Esta funo deve retornar 0 se a lista j era vazia antes de se tentar a remoo, ou 1 se a lista no era vazia (chamamos este valor inteiro de status). Ao invs de imprimir o valor retirado, ela deve passar este valor por referncia a um parmetro. Ela deve ser chamada assim:
status = pop(&lista, &x);

Soluo: veja no final. 8. Exerccio resolvido: crie uma funo que l uma quantidade qualquer de nmeros entrados pelo usurio e os imprime na ordem inversa de entrada, usando as funes push() e pop() (observao: com estas funes, implementamos uma pilha (LIFO)). Soluo: veja no final.

6. Exerccios resolvidos
Soluo do exerccio 5:
#include <stdio.h> #include <stdlib.h> #include <math.h>

struct no { float info; struct no *prox; };

typedef struct no * pno;

pno get_node(float x) { pno n = malloc(sizeof(struct no)); n->info = x; return n; }

void push(pno *lis, float x) { pno n = get_node(x); n->prox = *lis; *lis = n; }

void print_list(pno p) { printf("Imprimindo lista:\n"); while(p != NULL) { printf("%f ", p->info); p = p->prox; } printf("\n"); }

float media(pno p) { float m = 0; int n = 0; while(p != NULL) { m = m + p->info; n = n + 1; p = p->prox;

} return m / n; }

float desvio_padrao(pno p, float m) { float s = 0; int n = 0; while(p != NULL) { s = s + (p->info - m) * (p->info - m); n = n + 1; p = p->prox; } return sqrt(s / n); }

int main() { pno lista = NULL;

float x; char c;

float m, s;

do { printf("Digite um numero: "); scanf("%f", &x); push(&lista, x); printf("Mais um numero? (s/n): "); scanf(" %c", &c); } while(c != 'n');

print_list(lista);

m = media(lista); s = desvio_padrao(lista, m); printf("media = %f, desvio padrao = %f\n", m, s);

system("pause"); return 0; }

Soluo do exerccio 7 (apenas a funo pop() e a funo main(), as outras funes, a struct e o typedef devem ser iguais aos do exerccio acima).
/* A funo de remoo. */ /* l (o ponteiro inicial da lista) e n so passados por referncia. */ int pop(pno *l, int *n) { /* guarda o endereo do elemento a ser retirado: */ pno p = *l; /* verifica se a lista era vazia: */ if(p == NULL) return 0; /* passa o valor a ser retirado referncia n: */ *n = p->info; /* altera o ponteiro inicial para apontar ao segundo elemento: */ *l = p->prox; /* libera a memria ocupada pelo primeiro elemento */ free(p); /* retorna 1, pois a lista no era vazia: */ return 1; }

int main() { /* Ponteiro inicial da lista, inicialmente vazia: */ pno lista = NULL; /* usados para guardar os valores recebidos pelo pop: */ int status, x;

/* Trs elementos so inseridos: */ push(&lista, 10); push(&lista, 20); push(&lista, 30);

/* A lista imprimida: */ print_list(lista);

/* Remoo do primeiro elemento */ status = pop(&lista, &x); printf("status = %d, elemento removido: %d\n", status, x);

/* A lista novamente imprimida: */ print_list(lista);

system("pause"); return 0; }

Soluo do exerccio 8 (apenas a funo main(). O programa deve ser completado com o que falta)
int main() { pno lista = NULL; int x; char c;

/* Insere nmeros na lista at que o usurio digite n */ do { printf("Digite um numero: "); scanf("%d", &x); push(&lista, x); printf("Mais um numero? (s/n): "); scanf(" %c", &c); /* ateno, o espao antes de %c importante! */ } while(c != 'n');

/* retira os elementos da lista e os imprime um por um */ /* at que pop() retorne 0 (isto , a lista fique vazia) */ printf("Numeros na ordem inversa: "); while(pop(&lista, &x) != 0) { printf("%d ", x); } printf("\n");

system("pause"); return 0; }

Vous aimerez peut-être aussi