Você está na página 1de 10

23/09/2015

Agenda
Listas lineares

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

TAD para listas lineares


Alocao sequencial
Alocao encadeada

Definio de Listas Lineares

Listas Lineares
Maneira 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.

Adequadas quando no possvel prever a


demanda por memria

Sequncia 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.

TAD Listas Lineares


TAD: Agrupa a estrutura de dados juntamente com as
operaes que podem ser feitas sobre esses dados.
As duas representaes mais utilizadas so as
implementaes
Alocao sequencial
Alocao encadeada

Projetando TAD de 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.

23/09/2015

Implementao usando alocao sequencial

Projetando TAD de Listas Lineares

Localizao na memria:

Exemplo de Conjunto de Operaes:

Posies contguas.

Visita:

1) FLVazia(Lista). Faz a lista ficar vazia.

Pode ser percorrida em qualquer direo.


Permite acesso aleatrio.

2) Insere(x, Lista). Insere x aps o ltimo item da lista.


3) 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.

Insero:
Realizada aps o ltimo item com custo constante.
Um novo item no meio da lista custo no constante.

4) Vazia(Lista). Esta funo retorna true se lista vazia; seno retorna false.
5) Imprime(Lista). Imprime os itens da lista na ordem de ocorrncia.

Remoo:
Final da lista: custo constante
Meio ou incio: requer deslocamento de itens

Alocao Sequencial (estrutura)

Os itens armazenados em um array.


MaxTam define o tamanho mximo permitido
para 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 isima-1 posio do array, 0 i < ltimo.
(Item[i])
Item

#define InicioArranjo
#define MaxTam

Alocao Sequencial (estrutura)


0
1000

typedef int TipoChave;

typedef int Apontador;

typedef struct {
TipoChave Chave;
/* outros componentes */
} TipoItem;

Os itens armazenados em um array.


MaxTam define o tamanho mximo permitido
para 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 isima-1 posio do array, 0 i < ltimo.
(Item[i])
Item

typedef struct {
TipoItem Item[MaxTam];
Apontador Primeiro, Ultimo;
} TipoLista;

Os itens armazenados em um array.


MaxTam define o tamanho mximo permitido
para 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 isima-1 posio do array, 0 i < ltimo.
(Item[i])
Item

typedef int TipoChave;

typedef int Apontador;

typedef struct {
TipoItem Item[MaxTam];
Apontador Primeiro, Ultimo;
} TipoLista;

typedef int TipoChave;


typedef int Apontador;

typedef struct {
TipoChave Chave;
/* outros componentes */
} TipoItem;

Alocao Sequencial (estrutura)

const InicioArranjo = 0;
const MaxTam = 1000;

typedef struct {
TipoChave Chave;
/* outros componentes */
} TipoItem;

0
1000

typedef struct {
TipoItem Item[MaxTam];
Apontador Primeiro, Ultimo;
} TipoLista;

Alocao Sequencial (estrutura)

#define InicioArranjo
#define MaxTam

Os itens armazenados em um array.


MaxTam define o tamanho mximo permitido
para 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 isima-1 posio do array, 0 i < ltimo.
(Item[i])
Primeiro

Ultimo

Item
Item[0]
Item[1]

const InicioArranjo = 0;
const MaxTam = 1000;
typedef int TipoChave;
typedef int Apontador;
typedef struct {
TipoChave Chave;
/* outros componentes */
} TipoItem;
typedef struct {
TipoItem Item[MaxTam];
Apontador Primeiro, Ultimo;
} TipoLista;

MaxTam

23/09/2015

Alocao Sequencial (operaes)


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

Alocao Sequencial (operaes)

???
???
???
???

MaxTam

???
???
???

Ultimo

???
???
???

MaxTam

???

Alocao Sequencial (operaes)

???
???

void Insere(TipoItem x, TipoLista *Lista)


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

???
???
???
???

MaxTam

???

Alocao Sequencial (operaes)

???
???

MaxTam

Alocao Sequencial (operaes)

Primeiro

???

???

???

void Insere(TipoItem x, TipoLista *Lista)


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

???

Ultimo

Primeiro

/* testa se a lista est vazia */


int Vazia(const TipoLista *Lista)
{
return (Lista->Primeiro == Lista->Ultimo);
} /* Vazia */

Primeiro

Alocao Sequencial (operaes)


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

/* faz lista ficar vazia */


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

MaxTam

???

void Retira(Apontador p, TipoLista *Lista, TipoItem *Item) {


Apontador 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];
}

x
???

Ultimo

???
???

MaxTam

???

23/09/2015

Alocao Sequencial (operaes)

Alocao Sequencial (operaes)

void Retira(Apontador p, TipoLista *Lista, TipoItem *Item) {


Apontador 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];
}

void Retira(Apontador p, TipoLista *Lista, TipoItem *Item) {


Apontador 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];
}

Primeiro
p

Ultimo

Primeiro

x1

x3

???

???
Ultimo

Alocao Sequencial (operaes)

x2
x3
Ultimo

???
Ultimo

x1

Primeiro

Ultimo

???

???

for (i = Lista->Primeiro; i < Lista->Ultimo; i++)


printf("%d\n", Lista->Item[i].Chave);
}

x1

x1
x2

x2

x3

x3

x3

x3

???

???

Ultimo

???

void Imprime(const TipoLista *Lista){


Apontador i;

Primeiro
Primeiro

x2

Alocao Sequencial (operaes)

void Retira(Apontador p, TipoLista *Lista, TipoItem *Item) {


Apontador 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];
}

x1

x1
x3

x3

x2

???

Primeiro

Primeiro

x1

x2

???

???

???

???

Alocao Sequencial
Vantagens:
economia de memria, pois cada elemento da
lista armazena apenas os dados.
A estrutura da lista definida implicitamente
Acesso a um item qualquer CONSTANTE

Ultimo

???

Alocao Sequencial
Desvantagens:
custo para inserir ou retirar itens da lista, que
pode causar um deslocamento de todos os itens
no pior caso IGUAL AO TAMANHO DO VETOR: CUSTO
LINEAR!

O tamanho mximo da lista fixo e definido em


tempo de compilao!
Pouco til para aplicaes em que no existe previso
sobre o crescimento da lista.

23/09/2015

Alocao Sequencial
Como resolver o problema de tamanho fixo?

Alocao Encadeada
Permite utilizar posies no contguas de
memria
possvel inserir e retirar elementos sem
necessidade de deslocar os itens seguintes da
lista

Sobre os Elementos da Lista


Uma clula guarda as informaes sobre cada
elemento.
Cada clula possui:
campo de informaes
ponteiro para o prximo elemento

Alocao Encadeada
Caractersticas:
Tamanho da lista no pr-definido
Cada elemento guarda quem o prximo
Elementos no esto contguos na memria
info
info

NULL
prox
info
prox

info
info
prox

prox
info
NULL
prox

Alocao Encadeada
Uma lista encadeada pode ser organizada de
duas maneiras diferentes:
Lista sem cabea: A primeira clula contm
contedo.

Alocao Encadeada
Uma lista encadeada pode ser organizada de
duas maneiras diferentes:
Lista com cabea: O contedo da primeira clula
irrelevante. Essa clula apenas marcar o incio da
lista.

23/09/2015

Alocao Encadeada
Lista sem cabea
Operaes de Insero e Remoo exigem que
seja verificado se ponteiro para a primeiro clula
igual a NULL

Lista com cabea

Sobre a Lista
Uma lista definida como um apontador para
a primeira elemento
Uma lista pode ter um apontador para o
ltima clula

Evita os testes com a primeira clula e assim


melhora o desempenho

prox

info

info

info

prox

prox

NULL

ltimo

Primeiro

Implementao em C

Implementao em C
Celula

typedef int TipoChave;


3.14

typedef struct {
TipoChave Chave;
/* outros componentes */
} TipoItem;

Prox

typedef struct Celula_str *Apontador;

TipoLista

typedef struct Celula_str {


TipoItem Item;
Apontador Prox;
} Celula;

Celula
Primeiro

9.8

ltimo

Prox

NULL

typedef struct {
Apontador Primeiro, Ultimo;
} TipoLista;

Cria Lista Vazia

Insero de Elementos na Lista

Cabea

Primeiro

prox

NULL
prox

info

info

info

prox

prox

NULL

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

Primeiro

ltimo

3 opes de posio onde pode inserir:

1. posio
ltima posio
Aps um elemento qualquer E

23/09/2015

Insero na Primeira Posio

Insero na ltima Posio


Novo

Novo

info
NULL
prox

prox
info

info

info

prox

prox

NULL

info

info

info

info

prox

prox

NULL
prox
NULL

NULL

ltimo
prox
ltimo
Primeiro
Primeiro

Insero na Aps o Elemento E

Na verdade, as 3 opes de insero so


equivalentes a inserir aps uma clula
apontada por p

info

Novo
Primeiro

NULL
prox

prox

Insero de elementos na Lista

info

info

info

prox

prox

NULL

1 posio: p a clula cabea


ltima posio: p o ltimo
Aps um elemento qualquer E: p aponta para
E

ltimo

Elem E

Insero na Aps o Elemento E


novo

Primeiro
Elem E

Retirada de Elementos na Lista

info
NULL
prox
prox

prox

ltimo

info

info

info

prox

prox

NULL

void Insere(TipoItem x, TipoLista *lista, Apontador E){


Apontador novo;
novo = (Apontador) malloc(sizeof(Celula));
novo->Item = x;
novo->prox = E->prox;
E->prox = novo;

info

info

info

prox

prox

NULL

ltimo

3 opes de posio de onde pode retirar:

1. posio
ltima posio
Um elemento qualquer E

23/09/2015

Retirada do Elemento na
Primeira Posio da Lista

Retirada do ltimo Elemento da Lista

Temp

prox

info

info

info

prox

prox

NULL

prox

info

info

info

prox

NULL
prox

NULL

ltimo

Primeiro

Anterior
Primeiro

ltimo

Retirada do Elemento E da Lista

prox

Retirada do elemento aps E da Lista

info

info

info

prox

prox

NULL

prox

Primeiro
ltimo

Primeiro
Anterior

Elem E

Alocao Encadeada
Localizao na memria:
Posies no sequenciais

Visita:
Apenas na direo xi para xi+1.
Permite apenas acesso sequencial.

Insero:
Realizada em qualquer posio com custo constante.

Remoo:
Custo constante em qualquer posio.

ltimo

info

info

info

prox

prox

NULL

tmp

int RemoveProx(TipoLista *lista, Apontador E, TipoItem


*item){
Apontador tmp;
tmp = E->prox;
if (tmp != NULL) {
E->prox = tmp->prox; *item = tmp->item;
if (e->prox == NULL) lista->ultimo = e;
free(tmp);
return 1;
} else return 0;
}

Alocao Encadeada
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).

Desvantagens
Utilizao de memria extra para armazenar os
apontadores.
Custo linear para acessar um item no pior caso

23/09/2015

Exemplo: Ordenao

Exemplo: Ordenao

Problema: Ordenar uma lista com alocao encadeada em


tempo linear. Esta lista apresenta chaves inteiras com valores
entre 0 e 255.

Problema: Ordenar uma lista com alocao


encadeada em tempo linear. Esta lista
apresenta chaves inteiras com valores entre 0
e 255
1

241

dados1

dados2

dados3

dados4

prox

prox

prox

prox

31

...

241

dados1

dados2

dados3

dados4

prox

prox

prox

prox

dados5
NULL

dados5

NULL
Primeiro

Primeiro

31

...

ltimo

ltimo

Exemplo: Ordenao
Percorra lista original
Utilize a chave de cada elemento para indexar o vetor
Insira o elemento como ltimo elemento da lista
correspondente

Crie uma nova lista com alocao dinmica


Percorrer cada elemento do vetor em ordem
sequencial
Percorre cada item da lista correspondente
Insere item na nova lista

Exemplo: Ordenao
Soluo: Criar um vetor com 256 posies contendo
ponteiros para listas com alocao dinmica.
Lista 0
0
0

dados

dados

prox

prox

Encontre o primeiro nmero da lista.


Remova da lista todos os mltiplos do
nmero primo encontrado.

...

dados

NULL

...

Lista 255

255

Exemplo: Crivo de Eratstenes


Crie uma lista com nmeros de 2 at n.

255

255

dados

dados

prox

prox

255

...

dados
NULL

Avisos
Data das provas:
Prova 1: 13/10/2015
Prova 2: 10/11/2015

O prximo nmero da lista primo.


Repita o procedimento.

Prova 3: 15/12/2015

Ao final, a lista contm somente


nmeros primos.

23/09/2015

Avisos
TP0 disponvel em:
No moodle
exemplo_documentacao_aeds2.pdf
Entrega no dia 06/10/2015 at 23:55

Monitoria
Bernardo: Quarta: 15 s 17h (sala 3017)
Gabriel: Segunda: 13 s 15h (sala 3017)

10

Você também pode gostar