Вы находитесь на странице: 1из 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; }

Вам также может понравиться