listas com ponteiros listas encadeadas listas circulares

22
Listas com Ponteiros Listas encadeadas Listas circulares

Upload: internet

Post on 17-Apr-2015

200 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Listas com Ponteiros Listas encadeadas Listas circulares

Listas com Ponteiros

Listas encadeadas Listas circulares

Page 2: Listas com Ponteiros Listas encadeadas Listas circulares

Listas Simplesmente Encadeadas

A figura mostra como seria uma lista usando ponteiros para encadear os elementos da lista.

O ponteiro pt aponta para o nó inicial da lista. Cada nó está representado por um retângulo dividido em duas

partes. Uma das partes contém a informação e a outra o ponteiro para

o próximo nó. Observar que o no último nó a seta aponta para a terra, que

indica fim da lista.

Page 3: Listas com Ponteiros Listas encadeadas Listas circulares

Listas Simplesmente Encadeadas

A função listar mostra como percorrer uma lista encadeada simples.

void listar (struct tElemento *ptlista) {

int i=0; struct tElemento *pont;

pont = ptlista; while (pont) { printf("Elemento %d = %d\n", i++, pont->info); pont = pont->prox; }}

Page 4: Listas com Ponteiros Listas encadeadas Listas circulares

Listas Simplesmente Encadeadas

Outras funções relevantes em listas são: busca, inserção e remoção.

Para facilitar a busca e localização dos nós a serem removidos e das posições de inserção modificaremos a lista para incluir o que costuma ser chamado de nó cabeça.

Neste tipo de lista o primeiro nó não irá conter informação, ele apenas faz com que o algoritmo de busca não necessite diferenciar o primeiro nó dos demais.

Page 5: Listas com Ponteiros Listas encadeadas Listas circulares

Listas Simplesmente Encadeadas A função de busca a seguir é simples e tem como protótipo ponteiros para

ponteiros. O primeiro **ant aponta para o nó anterior ao nó procurado e **ponte aponta para o nó procurado.

void busca ( tElemento *ptlista, int x, tElemento **ant, tElemento **ponte) { /* *ptlista ponteiro para inicio da lista x elemento a ser procurado **ant ponteiro para ponteiro do elemento anterior **pont ponteiro para ponteiro do elemento procurado */

tElemento *ptr; *ant = ptlista; /* aponta no anterior */ *ponte = NULL; /* aponta no procurado, se nao achar retorna nulo */ ptr = ptlista->prox; /* aponta no procurado */

while (ptr) { /* procura enquanto houver chance */ if (ptr->info < x) { /* ainda nao chegou no no */ *ant = ptr; ptr = ptr->prox; } else { /* pode ser aqui */ if (ptr->info == x) *ponte = ptr; /* achou */ ptr = NULL; /* nao estava na lista */ } }}

Page 6: Listas com Ponteiros Listas encadeadas Listas circulares

Listas Simplesmente Encadeadas

A figura a seguir mostra a remocao de lista encadeada com nó cabeça e sua respectiva função.

void remover ( tElemento *ptlista) { int x; char linha[80]; tElemento **ant, **pont;

printf("Valor a remover? "); fgets(linha, 80, stdin); sscanf(linha, "%d", &x);

ant = ( tElemento **) malloc(sizeof ( tElemento *)); pont = ( tElemento **) malloc(sizeof ( tElemento *)); busca (ptlista, x, ant, pont); if (*pont) { (*ant)->prox = (*pont)->prox; printf("Retirei %d\n", (*pont)->info); free(*pont); } else puts("Nao achei na lista.");}

Page 7: Listas com Ponteiros Listas encadeadas Listas circulares

Listas Simplesmente Encadeadas O algoritmo de inserção tem o seguinte código: void inserir ( tElemento *ptlista) { tElemento *pt, /* ponteiro para o novo no a inserir */ **ant, /* ponteiro para ponteiro na lista */ **pont; /* ponteiro para ponteiro do no anterior */ int x; char linha[80]; printf("Valor a inserir? "); fgets(linha, 80, stdin); sscanf(linha, "%d", &x); ant = ( tElemento **) malloc(sizeof ( tElemento *)); pont = ( tElemento **) malloc(sizeof ( tElemento *));

busca (ptlista, x, ant, pont); if (!*pont) { pt = ( tElemento *) malloc(sizeof( tElemento)); pt->info = x; pt->prox = (*ant)->prox; (*ant)->prox = pt; } else puts("Elemento ja existe na tabela."); }

Page 8: Listas com Ponteiros Listas encadeadas Listas circulares

Exercício

Escreva um programa em C que implemente todas as funções apresentadas e as disponibilize em um menu.

Page 9: Listas com Ponteiros Listas encadeadas Listas circulares

Listas circulares

O algoritmo de busca em uma lista encadeada pode ser melhorado se modificarmos a lista de modo que ela passe a ser circular como está mostrado a seguir:

Neste caso o algoritmo não tem como testar o final da lista. A solução é armazenar o dado que se está procurando no nó cabeça.

Ao término do algoritmo a chave é sempre encontrada, e pode-se descobrir se ela pertencia ou não a lista pelo ponteiro que foi dado como resposta.

Caso o ponteiro termine apontando para o nó cabeça, podemos afirmar que o elemento não se encontra na lista.

Page 10: Listas com Ponteiros Listas encadeadas Listas circulares

Listas circulares

As funções de procura, inserção e remoção em uma lista circular encadeada serão mostrados a seguir.

O algoritmo de busca aparece como parte das rotinas de inserção e remoção.Nestas funções primeiro se procura o elemento depois se decide o que fazer.

No algoritmo de busca, caso o elemento já exista na lista, não há nada a fazer, caso contrário o ponteiro ant aponta para o elemento após o qual o novo elemento será inserido.

Na função de remoção, a busca termina apontando para o elemento a ser removido (ponteiro pont) ou com a indicação que o elemento não se encontra na lista (pont apontando para o nó cabeça).

Page 11: Listas com Ponteiros Listas encadeadas Listas circulares

Listas circulares

Definição da estrutura:

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

char menu(); struct tElemento *cria_no();

Page 12: Listas com Ponteiros Listas encadeadas Listas circulares

Listas circulares

Função menu:

char menu () { char opcao, linha[80];

puts("Qual a sua opcao?"); puts("[L]istar, [I]nserir, [R]emover, [S]air"); gets(linha); sscanf(linha, "%c", &opcao); return tolower(opcao); }

Page 13: Listas com Ponteiros Listas encadeadas Listas circulares

Listas circulares

Função listar:

void listar (struct tElemento *ptlista) { int i=0; struct tElemento *pont; pont = ptlista->prox; while (pont != ptlista) { printf("Elemento %d = %d\n", i++, pont->info); pont = pont->prox; } }

Page 14: Listas com Ponteiros Listas encadeadas Listas circulares

Listas circulares Função insere:void insere (struct tElemento *ptlista, int valor) { struct tElemento *pont, *ant, *pt; /* Aqui esta o algoritmo de busca em uma lista circular */ ant = ptlista; pont = ptlista->prox; ptlista->info = valor; while (pont->info < valor) { ant = pont; pont = pont->prox; } if (pont->info == valor && pont != ptlista) puts("Elemento ja existe na tabela."); else { pt = cria_no(); pt->info = valor; pt->prox = pont; ant->prox = pt; } }

Page 15: Listas com Ponteiros Listas encadeadas Listas circulares

Listas circulares Função remove:void meu_remove (struct tElemento *ptlista, int valor) { struct tElemento *pont, *ant; ant = ptlista; pont = ptlista->prox; ptlista->info = valor; while (pont->info < valor) { if (pont->info < valor) { ant = pont; pont = pont->prox; } } if (pont->info == valor && pont != ptlista) { ant->prox = pont->prox; free(pont); } else puts("Elemento nao existe na tabela."); }

Page 16: Listas com Ponteiros Listas encadeadas Listas circulares

Listas circulares

Função cria nó:

struct tElemento *cria_no() { struct tElemento *pt; if (( pt = (struct tElemento *) malloc(sizeof(struct tElemento)) )

== NULL ) { puts("Nao há espaço."); exit(1); } pt->info = -1; pt->prox = NULL; return pt; }

Page 17: Listas com Ponteiros Listas encadeadas Listas circulares

Exercício

Escreva um programa em C que implemente todas as funções apresentadas.

Page 18: Listas com Ponteiros Listas encadeadas Listas circulares

PilhasUma pilha é uma lista em que os elementos são inseridos e

removidos sempre pelo topo da pilha. A figura mostra

como se processam operações que envolvem acesso a uma pilha.

Page 19: Listas com Ponteiros Listas encadeadas Listas circulares

Pilhas - Listar

Uma imagem simples pode ilustrar o funcionamento das pilhas.Considere um restaurante onde os clientes do tipo self-service.Neste restaurante, para se servirem, os clientes retiram pratos e os

empregados colocam pratos limpos em uma pilha. Observe que os empregados colocam pratos no topo da pilha, o

mesmo local de onde os clientes retiram os pratos.A função abaixo lista o conteúdo de uma pilha:

void listar (int item[], int topo) { /* Esta rotina esta aqui somente para depuracao */ int i; for (i=0; i<topo; i++) printf("elemento %d = %d \n", i, item[i]);}

Page 20: Listas com Ponteiros Listas encadeadas Listas circulares

Pilhas - Inserir

A função abaixo insere no topo da pilha:

void insere (int item[], int *topo) { int t; char linha[80]; printf("Valor a inserir? "); gets(linha); sscanf(linha, "%d", &t); if (*topo < MAX) { *topo=*topo+1; item[*topo] = t; printf("Topo = %d\n", *topo); } else puts("Pilha cheia.");}

Page 21: Listas com Ponteiros Listas encadeadas Listas circulares

Pilhas - Remover

A função a seguir retira um elemento do topo da pilha:

void meu_remove (int item[], int *topo) { int x; if (*topo != -1) { x = item[*topo]; *topo = *topo-1; printf("Retirei %d da pilha.\n", x); } else puts("Lista vazia"); }

Page 22: Listas com Ponteiros Listas encadeadas Listas circulares

Exercícios

1. Implemente um programa em C que utilize as funções descritas anteriormente para realizar operações em Pilhas.

2. Adapte o programa anterior para que o mesmo realize operações em Filas, isto é, insira pelo topo e retire pelo fundo.

3. Escreva um programa que, utilizando a estrutura de pilhas, avalie uma expressão em notação polonesa reversa.