Você está na página 1de 37

Listas Lineares

Livro Projeto de Algoritmos Nvio Ziviani Captulo 3 Seo 3.1 http://www2.dcc.ufmg.br/livros/algoritmos/

Listas Lineares

Uma das formas mais simples de representar elementos de um conjunto.


Itens podem ser acessados, inseridos ou retirados de uma lista. Podem crescer ou diminuir de tamanho durante a execuo de um programa, de acordo com a demanda.
Algoritmos e Estrutura de Dados II

Listas Lineares

Adequadas quando no possvel prever a demanda por memria, permitindo a manipulao de quantidades imprevisveis de dados, de formato tambm imprevisvel. So teis em aplicaes tais como manipulao simblica, gerncia de memria, simulaes e compiladores.
Algoritmos e Estrutura de Dados II

Definio de Listas Lineares

Seqncia de zero ou mais itens

x1 ,x2 ,,xn , na qual xi de um determinado tipo e n representa o tamanho da lista linear.

Sua principal propriedade estrutural envolve as posies relativas dos itens em uma dimenso.

Assumindo n 1, x1 o primeiro item da lista

e xn o ltimo item

da lista.

xi precede xi+1 para i = 1,2,,n 1 xi sucede xi-1 para i = 2,3,,n o elemento xi dito estar na i-sima posio da lista.
Algoritmos e Estrutura de Dados II

TAD Listas Lineares

O conjunto de operaes a ser definido depende de cada aplicao. Um conjunto de operaes necessrio a uma maioria de aplicaes :
1) 2) 3) 4)

5) 6) 7) 8)

9)

Criar uma lista linear vazia. Inserir um novo item imediatamente aps o i-simo item. Retirar o i-simo item. Localizar o i-simo item para examinar e/ou alterar o contedo de seus componentes. Combinar duas ou mais listas lineares em uma lista nica. Partir uma lista linear em duas ou mais listas. Fazer uma cpia da lista linear. Ordenar os itens da lista em ordem ascendente ou descendente, de acordo com alguns de seus componentes. Pesquisar a ocorrncia de um item com um valor particular em algum componente.
Algoritmos e Estrutura de Dados II

Implementaes de Listas Lineares

Vrias estruturas de dados podem ser usadas para representar listas lineares, cada uma com vantagens e desvantagens particulares. As duas representaes mais utilizadas so as implementaes por meio de arranjos e de apontadores. Exemplo de Conjunto de Operaes:
1)
2) 3)

FLVazia(Lista). Faz a lista ficar vazia.


Insere(x, Lista). Insere x aps o ltimo item da lista. Retira(p, Lista, x). Retorna o item x que est na posio p da lista, retirando-o da lista e deslocando os itens a partir da posio p+1 para as posies anteriores. Vazia(Lista). Esta funo retorna true se lista vazia; seno retorna false. Imprime(Lista). Imprime os itens da lista na ordem de ocorrncia.
Algoritmos e Estrutura de Dados II

4) 5)

Implementao de Listas por meio de Arranjos


Os itens da lista so armazenados em posies contguas de memria. A lista pode ser percorrida em qualquer direo. A insero de um novo item pode ser realizada aps o ltimo item com custo constante. A insero de um novo item no meio da lista requer um deslocamento de todos os itens localizados aps o ponto de insero. Retirar um item do incio da lista requer um deslocamento de itens para preencher o espao deixado vazio.
Algoritmos e Estrutura de Dados II

Estrutura da Lista Usando Arranjo

Os itens so armazenados em um array de tamanho suficiente para armazenar a lista.


O campo ltimo aponta para a posio seguinte a do ltimo elemento da lista. (primeira posio vazia) O i-simo item da lista est armazenado na i-sima-1 posio do array, 0 i < ltimo. A constante MaxTam define o tamanho mximo permitido para a lista.
Algoritmos e Estrutura de Dados II

Estrutura da Lista Usando Arranjo


#define InicioArranjo #define MaxTam typedef int TipoChave; typedef int Apontador; typedef struct { TipoChave Chave; /* outros componentes */ } TipoItem; typedef struct { TipoItem Item[MaxTam]; Apontador Primeiro, Ultimo; } TipoLista;
Algoritmos e Estrutura de Dados II

0 1000

Operaes sobre Lista Usando Arranjo


void FLVazia(TipoLista *Lista) { Lista->Primeiro = InicioArranjo; Lista->Ultimo = Lista->Primeiro; } /* FLVazia */

int Vazia(TipoLista Lista) { return (Lista.Primeiro == Lista.Ultimo); } /* Vazia */

Algoritmos e Estrutura de Dados II

Operaes sobre Lista Usando Arranjo


void Insere(TipoItem x, TipoLista *Lista) { if (Lista->Ultimo >= MaxTam) printf("Lista esta cheia\n"); else { Lista->Item[Lista->Ultimo] = x; Lista->Ultimo++; } } /* Insere */

Algoritmos e Estrutura de Dados II

Operaes sobre Lista Usando Arranjo


void Retira(Apontador p, TipoLista *Lista, TipoItem *Item) { int Aux; if (Vazia(*Lista) || p >= Lista->Ultimo) { printf(" Erro: Posicao nao existe\n"); return; } *Item = Lista->Item[p]; Lista->Ultimo--; for (Aux = p+1; Aux <= Lista->Ultimo; Aux++) Lista->Item[Aux - 1] = Lista->Item[Aux]; }
Algoritmos e Estrutura de Dados II

Operaes sobre Lista Usando Arranjo


void Imprime(TipoLista Lista) { Apontador Aux; for (Aux=Lista.Primeiro; Aux<=(Lista.Ultimo - 1); Aux++) printf("%d\n", Lista.Item[Aux].Chave);
}

Algoritmos e Estrutura de Dados II

Lista Usando Arranjo - Vantagens e Desvantagens

Vantagem:

economia de memria (os apontadores so implcitos nesta estrutura). Acesso a um item qualquer O(1).

Desvantagens:

custo para inserir ou retirar itens da lista, que pode causar um deslocamento de todos os itens, no pior caso; em aplicaes em que no existe previso sobre o crescimento da lista, a utilizao de arranjos em linguagens como o Pascal pode ser problemtica porque neste caso o tamanho mximo da lista tem de ser definido em tempo de compilao.
Algoritmos e Estrutura de Dados II

Implementao de Listas por meio de Apontadores

Cada item encadeado com o seguinte mediante uma varivel do tipo Apontador.
Permite utilizar posies no contguas de memria. possvel inserir e retirar elementos sem necessidade de deslocar os itens seguintes da lista.

H uma clula cabea para simplificar as operaes sobre a lista.

Algoritmos e Estrutura de Dados II

Estrutura da Lista Usando Apontadores

A lista constituda de clulas.


Cada clula contm um item da lista e um apontador para a clula seguinte. O registro TipoLista contm um apontador para a clula cabea e um apontador para a ltima clula da lista.

Algoritmos e Estrutura de Dados II

typedef int TipoChave;

Estrutura da Lista Usando Apontadores

typedef struct { TipoChave Chave; /* outros componentes */ } TipoItem; typedef struct Celula { TipoItem Item; struct Celula * Prox; } Celula; typedef struct Celula * Apontador; typedef struct { Apontador Primeiro, Ultimo; } TipoLista;
Algoritmos e Estrutura de Dados II

Operaes sobre Lista Usando Apontadores


void FLVazia(TipoLista *Lista) { Lista->Primeiro = (Apontador) malloc(sizeof(Celula)); Lista->Ultimo = Lista->Primeiro; Lista->Primeiro->Prox = NULL; }

int Vazia(TipoLista Lista) { return (Lista.Primeiro == Lista.Ultimo); }


Algoritmos e Estrutura de Dados II

Operaes sobre Lista Usando Apontadores


void Insere(TipoItem x, TipoLista *Lista) { Lista->Ultimo->Prox = (Apontador) malloc(sizeof(Celula));
Lista->Ultimo = Lista->Ultimo->Prox; Lista->Ultimo->Item = x; Lista->Ultimo->Prox = NULL;

Algoritmos e Estrutura de Dados II

Operaes sobre Lista Usando Apontadores


void Retira(Apontador p, TipoLista *L, TipoItem *Item) {
/* o item a ser retirado e o seguinte ao apontado por p */

Apontador q;

if (Vazia(*L) || p == NULL || p->Prox == NULL) { printf(" Erro: Lista vazia posio no existe"); return; } q = p->Prox; *Item = q->Item; p->Prox = q->Prox; if (p->Prox == NULL) L->Ultimo = p; free(q);
}
Algoritmos e Estrutura de Dados II

Operaes sobre Lista Usando Apontadores


void Imprime(TipoLista Lista) { Apontador Aux; Aux = Lista.Primeiro->Prox; while (Aux != NULL) { printf("%d\n", Aux->Item.Chave); Aux = Aux->Prox; } }

Algoritmos e Estrutura de Dados II

Operaes sobre Lista Usando Apontadores

Vantagens:

Permite inserir ou retirar itens do meio da lista a um custo constante (importante quando a lista tem de ser mantida em ordem). Bom para aplicaes em que no existe previso sobre o crescimento da lista (o tamanho mximo da lista no precisa ser definido a priori).

Desvantagem:

Utilizao de memria extra para armazenar os apontadores. O(n) para acessar um item no pior caso

Algoritmos e Estrutura de Dados II

Exemplo de Uso Listas - Vestibular

Num vestibular, cada candidato tem direito a trs opes para tentar uma vaga em um dos sete cursos oferecidos. Para cada candidato lido um registro:

Chave: nmero de inscrio do candidato. NotaFinal: mdia das notas do candidato.

Opo: vetor contendo a primeira, a segunda e a terceira opes de curso do candidato.

Algoritmos e Estrutura de Dados II

Exemplo de Uso Listas - Vestibular

Problema: distribuir os candidatos entre os cursos, segundo a nota final e as opes apresentadas por candidato. Em caso de empate, os candidatos sero atendidos na ordem de inscrio para os exames.

Algoritmos e Estrutura de Dados II

Vestibular - Possvel Soluo

Ordenar registros pelo campo NotaFinal, respeitando a ordem de inscrio; Percorrer cada conjunto de registros com mesma NotaFinal, comeando pelo conjunto de NotaFinal 10, seguido pelo de NotaFinal 9, e assim por diante. Para um conjunto de mesma NotaFinal tenta-se encaixar cada registro desse conjunto em um dos cursos, na primeira das trs opes em que houver vaga (se houver).

Algoritmos e Estrutura de Dados II

Vestibular - Possvel Soluo

Primeiro refinamento:

program Vestibular ; begin ordena os registros pelo campo NotaFinal ; for Nota := 10 downto 0 do while houver registro com mesma nota do if existe vaga em um dos cursos de opcao do candidato then insere registro no conjunto de aprovados else insere registro no conjunto de reprovados; imprime aprovados por curso ; imprime reprovados; end.

Algoritmos e Estrutura de Dados II

Vestibular - Classificao dos Alunos

Uma boa maneira de representar um conjunto de registros com o uso de listas. Ao serem lidos, os registros so armazenados em listas para cada nota. Aps a leitura do ltimo registro os candidatos esto automaticamente ordenados por NotaFinal. Dentro de cada lista, os registros esto ordenados por ordem de inscrio, desde que os registros sejam lidos na ordem de inscrio de cada candidato e inseridos nesta ordem.

Algoritmos e Estrutura de Dados II

Vestibular - Classificao dos Alunos

As listas de registros so percorridas, iniciando-se pela de NotaFinal 10, seguida pela de NotaFinal 9, e assim sucessivamente. Cada registro retirado e colocado em uma das listas da abaixo, na primeira das trs opes em que houver vaga. Aps a leitura do ltimo registro os candidatos esto automaticamente ordenados por NotaFinal. Dentro de cada lista, os registros esto ordenados por ordem de inscrio, desde que os registros sejam lidos na ordem de inscrio de cada candidato e inseridos nesta ordem.

Algoritmos e Estrutura de Dados II

Vestibular - Classificao dos Alunos

Se no houver vaga, o registro colocado em uma lista de reprovados. Ao final a estrutura acima conter a relao de candidatos aprovados em cada curso.

Algoritmos e Estrutura de Dados II

Vestibular - Segundo Refinamento


program Vestibular; begin l nmero de vagas para cada curso; inicializa listas de classificao de aprovados e reprovados; l registro; while Chave <> 0 do begin insere registro nas listas de classificao, conforme nota final; l registro; end;

Algoritmos e Estrutura de Dados II

Vestibular - Segundo Refinamento


for Nota := 10 downto 0 do while houver prximo registro com mesma NotaFinal do begin retira registro da lista; if existe vaga em um dos cursos de opo do candidato then begin insere registro na lista de aprovados; decrementa o nmero de vagas para aquele curso; end else insere registro na lista de reprovados; obtm prximo registro; end; imprime aprovados por curso; imprime reprovados; end.

Algoritmos e Estrutura de Dados II

Vestibular - Estrutura Final da Lista


#define #define #define #define NOpcoes NCursos FALSE TRUE 3 7 0 1

typedef short TipoChave; typedef struct TipoItem { TipoChave Chave; char NotaFinal; char Opcao[NOpcoes]; } TipoItem; typedef struct Celula { TipoItem Item; struct Celula *Prox; } Celula;

typedef struct TipoLista { Celula *Primeiro, *Ultimo; } TipoLista;


Algoritmos e Estrutura de Dados II

Vestibular - Estrutura Final da Lista


TipoItem Registro; TipoLista Classificacao[11]; TipoLista Aprovados[NCursos]; TipoLista Reprovados; long Vagas[NCursos]; short Passou; long i, Nota;

Algoritmos e Estrutura de Dados II

Vestibular - Refinamento Final

Observe que o programa completamente independente da implementao do tipo abstrato de dados Lista.
void LeRegistro(TipoItem *Registro) { /*---os valores lidos devem estar separados por brancos---*/ long i; int TEMP; scanf("%hd%d", &Registro->Chave, &TEMP); Registro->NotaFinal = TEMP; for (i = 0; i < NOpcoes; i++) { scanf("%d", &TEMP); Registro->Opcao[i] = TEMP; } scanf("%*[^\n]"); getchar(); }

Algoritmos e Estrutura de Dados II

Vestibular - Refinamento Final


int main(int argc, char *argv[]) { /*---Programa principal---*/ for (i = 1; i <= NCursos; i++) scanf("%ld", &Vagas[i-1]); scanf("%*[^\n]"); getchar(); for (i = 0; i <= 10; i++) FLVazia(&Classificacao[i]); for (i = 1; i <= NCursos; i++) FLVazia(&Aprovados[i-1]); FLVazia(&Reprovados); LeRegistro(&Registro); while (Registro.Chave != 0) { Insere(Registro, &Classificacao[Registro.NotaFinal]); LeRegistro(&Registro); }

Algoritmos e Estrutura de Dados II

Vestibular - Refinamento Final


for (Nota = 10; Nota >= 0; Nota--) { while (!Vazia(Classificacao[Nota])) { Retira(Classificacao[Nota].Primeiro, &Classificacao[Nota], &Registro); i = 1; Passou = FALSE; while (i <= NOpcoes && !Passou) { if (Vagas[Registro.Opcao[i-1] - 1] > 0) { Insere(Registro, &Aprovados[Registro.Opcao[i-1] - 1]); Vagas[Registro.Opcao[i-1] - 1]--; Passou = TRUE; } i++; } if (!Passou) Insere(Registro, &Reprovados); } } for (i = 1; i <= NCursos; i++) { printf("Relacao dos aprovados no Curso%ld\n", i); Imprime(Aprovados[i-1]); } printf("Relacao dos reprovados\n"); Imprime(Reprovados); return 0; Algoritmos e Estrutura de Dados II }

Vestibular - Refinamento Final

O exemplo mostra a importncia de utilizar tipos abstratos de dados para escrever programas, em vez de utilizar detalhes particulares de implementao. Altera-se a implementao rapidamente. No necessrio procurar as referncias diretas s estruturas de dados por todo o cdigo. Este aspecto particularmente importante em programas de grande porte.

Algoritmos e Estrutura de Dados II

Você também pode gostar