Você está na página 1de 13

Programacao

LEE
DEEC - IST

Listas ordenadas

Lista ordenada simples


verifica uma dada relacao
de
Uma lista ordenada e uma estrutura ligada cuja construcao
ordem entre os seus elementos.
de dados em listas ordenadas implica a criacao
de um registo adicional, pro A insercao
e proceder a` alteracao
dos apontadores no local de insercao.

curar o local de insercao


de listas ordenadas e em geral simples, requerendo no entanto alguma
A manipulacao
especial para o tratamento de casos especiais (remocao
e insercao
de elemenatencao
tos no final ou na base da lista, por exemplo).

7
base

14
(NULL)

Fernando Mira da Silva

Programacao
LEE
DEEC - IST

Listas ordenadas

Listas: listar elementos


de tipos
Declaracao
#include <stdio.h>
#include <stdlib.h>
typedef int tipoDados;
typedef struct _tipoLista {
tipoDados dados;
struct _tipoLista *seg;
} tipoLista;
Inicializar
tipoLista *inicializa(){
return NULL;
}
Listar todos os elementos
void listar(tipoLista *base ){
Fernando Mira da Silva


Programacao
LEE
DEEC - IST

Listas ordenadas

while(base){
printf(" -> ");
printf("%d\n",base -> dados);
base = base -> seg;
}
}

Fernando Mira da Silva

Programacao
LEE
DEEC - IST

Listas ordenadas

Listas: procura
Procura exaustiva e procura optimizada
tipoLista *procura(tipoLista *base,tipoDados x){
while((base!=NULL) && !(base -> dados != x))
base = base -> seg;
return base;
}
tipoLista *procuraOrdenado
(tipoLista *base,tipoDados x){
while((base!=NULL) && (base -> dados < x))
base = base -> seg;
if((base != NULL) && (base -> dados == x))
return base;
else
return NULL;
}
Fernando Mira da Silva


Programacao
LEE
DEEC - IST

Listas ordenadas

Listas: inserir
compacta
Inserir um registo na lista: versao
tipoLista *insereOrdenado(tipoLista *base,tipoDados x){
/*
ao compacta
* Vers
*/
tipoLista *aux = base, *reg = novoNo(x);

if(aux == NULL || x < aux -> dados) {


/* Lista vazia ou inserc

ao
antes da base
*/
reg -> seg = base;
return reg;
}

Fernando Mira da Silva

Programacao
LEE
DEEC - IST

Listas ordenadas

/* Procura ponto de inserc

ao */
aux = base;
while( aux -> seg!= NULL
&& aux -> seg -> dados < x)
aux = aux -> seg;
reg -> seg = aux -> seg;
aux -> seg = reg;
return base;
}

Fernando Mira da Silva


Programacao
LEE
DEEC - IST

Listas ordenadas

Listas: remover
Remover um registo da lista
tipoLista *libertaReg(tipoLista *reg){
tipoLista *aux;
aux = reg; reg = reg -> seg;
free(aux);
return reg;
}
tipoLista *apaga(tipoLista *base,tipoDados x){
tipoLista *aux;
if(base != NULL){
if(base -> dados == x){
base = libertaReg(base);
}
else{
aux = base;
while((aux -> seg != NULL) &&
Fernando Mira da Silva

Programacao
LEE
DEEC - IST

Listas ordenadas

(aux -> seg -> dados != x))


aux = aux -> seg;
if((aux -> seg != NULL ) &&
(aux -> seg -> dados == x))
aux -> seg = libertaReg(aux -> seg);
}
}
return base;
}

Fernando Mira da Silva


Programacao
LEE
DEEC - IST

Listas ordenadas

Listas: programa de teste


#include <stdio.h>
#include <stdlib.h>
#include "lista.h"
#define DIM_LINE 100
tipoDados leDados(char mensagem[]){
char line[DIM_LINE];
tipoDados x;
int ni;
do{
printf("%s ",mensagem);
fgets(line,DIM_LINE,stdin);
ni=sscanf(line,"%d",&x);
if(ni != 1) printf("Erro na leitura\n");
Fernando Mira da Silva

Programacao
LEE
DEEC - IST

Listas ordenadas

}while(ni != 1);
return x;
}

Fernando Mira da Silva

10


Programacao
LEE
DEEC - IST

Listas ordenadas

int main(){
tipoLista *base;
tipoDados x;
base = inicializa();
x = leDados("Indique um inteiro: ");
while(x != 0) {
if(x > 0){
base = insereOrdenado(base,x);
}
else{
x = -x;
if(procuraOrdenado(base,x) == NULL){
printf("%d nao encontrado\n",x);
}
else{
base = apaga(base,x);

Fernando Mira da Silva

Programacao
LEE
DEEC - IST

11

Listas ordenadas

}
}
listar(base);
x = leDados("Indique um inteiro: ");
}
exit(0);
}

Fernando Mira da Silva

12


Programacao
LEE
DEEC - IST

Listas ordenadas

Lista com registo separado para a base

de uma lista ligada resulta dos casos particulares


Parte da complexidade de manipulacao

que devem ser tratados explicitamente pelo codigo.


Uma forma de reduzir esta complexidade e alterar a estrutura da lista de modo a simplificar o tratamento de casos particulares.
na lista pode ser simplificada pela criacao
de um registo vazio
Em particular, a insercao

na base da lista, nunca utilizado na pratica.

base

14
(NULL)

Registo de base
(no utilizado)

Fernando Mira da Silva

Programacao
LEE
DEEC - IST

13

Listas ordenadas

Lista com registo separado para a base


Inicializar
tipoLista *inicializa(){
tipoLista *aux;
aux = (tipoLista*) calloc(1,sizeof(tipoLista));
aux -> seg = NULL;
return aux;
}
Inserir
void insereOrdenado(tipoLista *base,
tipoDados x){
tipoLista *act,*ant;
ant = base; act = base -> seg;
Fernando Mira da Silva

14


Programacao
LEE
DEEC - IST

Listas ordenadas

while((act != NULL) && (act -> dados < x)){


/*

ao
* Procura local de inserc
*/
ant = act; act = act -> seg;
}
insere(&(ant -> seg),x,act);
}

Fernando Mira da Silva

Programacao
LEE
DEEC - IST

15

Listas ordenadas

Lista com registo separado para a base: listagem e procura


Listar
void listar(tipoLista *base ){
base = base -> seg;
while(base){
printf(" -> %d\n",base -> dados);
base = base -> seg;
}
}
Procura
tipoLista *procura(tipoLista *base,tipoDados x){
base = base -> seg;
while((base!=NULL) && (base -> dados != x))
base = base -> seg;
return base;
}
Fernando Mira da Silva

16


Programacao
LEE
DEEC - IST

Listas ordenadas

tipoLista *procuraOrdenado(tipoLista *base,


tipoDados x){
base = base -> seg;
while((base!=NULL) && (base -> dados < x))
base = base -> seg;
if((base != NULL) && (base -> dados == x))
return base;
else
return NULL;
}

Fernando Mira da Silva

17

Programacao
LEE
DEEC - IST

Listas duplas e aneis

Listas duplas e aneis


de estruturas ligadas e facilitada com a inclusao,
em cada elemento, de
A manipulacao
um apontador para o seu predecessor.
sao
facilitadas
Apesar da maior complexidade da estrutura, a maioria das operacoes
Uma lista duplamente ligada e referenciada por dois apontadores, um para a base e outro
para o topo.
base

11

topo

Um anel duplo e uma lista duplamente ligada em que o ultimo

elemento aponta para o


primeiro.
de um registo separado para a base
Tal como no caso de listas simples, a utilizacao

facilita as operacoes
base

Fernando Mira da Silva

11

18


Programacao
LEE
DEEC - IST

Listas duplas e aneis

e inicializacao

Anel duplo: declaracao


de tipos
Declaracao
typedef int tipoDados;
typedef struct _tipoAnel {
tipoDados dados;
struct _tipoAnel *seg,*ant;
} tipoAnel;
Inicializar
tipoAnel *inicializa(){
tipoAnel *aux;
aux = (tipoAnel*) calloc(1,sizeof(tipoAnel));
aux -> seg = aux -> ant = aux;
return aux;
}
Fernando Mira da Silva

19

Programacao
LEE
DEEC - IST

Listas duplas e aneis

Anel duplo: inserir

Insercao
tipoAnel *novoNo(tipoDados x){
tipoAnel *novo = (tipoAnel*) calloc(1,sizeof(tipoAnel));
if(novo == NULL){
fprintf(stderr,"Erro na reserva de mem
oria\n");
exit(1);
}
novo -> dados = x;
return novo;
}
void insere(tipoAnel *depois,tipoDados x){
tipoAnel *reg = novoNo(x);
reg -> seg = depois;
reg -> ant = depois -> ant;
depois -> ant = reg;
reg -> ant -> seg = reg;
Fernando Mira da Silva

20


Programacao
LEE
DEEC - IST

Listas duplas e aneis

}
void insereOrdenado(tipoAnel *base,tipoDados x){
tipoAnel *act;
base -> dados = x;
act = base -> seg;
while(act -> dados < x){
/*

ao
* Procura local de inserc
*/
act = act -> seg;
}
insere(act,x);
}

Fernando Mira da Silva

21

Programacao
LEE
DEEC - IST

Listas duplas e aneis

Anel duplo: apagar


Apagar
void libertaReg(tipoAnel *reg){
reg -> seg -> ant = reg -> ant;
reg -> ant -> seg = reg -> seg;
free(reg);
}
void apaga(tipoAnel *base,tipoDados x){
tipoAnel *aux;
base -> dados = x;
aux = base -> seg;
while(aux -> dados < x)
aux = aux -> seg;
if((aux != base) && (aux -> dados == x))
libertaReg(aux);
}
Fernando Mira da Silva

22


Programacao
LEE
DEEC - IST

Listas duplas e aneis

Anel duplo: procurar


Procura
tipoAnel *procura(tipoAnel *base,tipoDados x){
tipoAnel *aux;
base -> dados = x;
aux = base -> seg;
while(aux -> dados != x)
aux = aux -> seg;
return (aux == base ? NULL : aux);
}
tipoAnel *procuraOrdenado(tipoAnel *base,tipoDados x){
tipoAnel *aux;
base -> dados = x;
aux = base -> seg;
while(aux -> dados < x)
Fernando Mira da Silva

Programacao
LEE
DEEC - IST

23

Listas duplas e aneis

aux = aux -> seg;


if((aux != base) && (aux -> dados == x))
return aux;
else
return NULL;
}

Fernando Mira da Silva

24


Programacao
LEE
DEEC - IST

Listas duplas e aneis

Anel duplo: listar


Listagem directa
void listar(tipoAnel *base ){
tipoAnel *aux;
aux = base -> seg;
while(aux != base){
printf(" -> %d \n",aux -> dados);
aux = aux -> seg;
}
}
void listarInv(tipoAnel *base ){
tipoAnel *aux;
aux = base -> ant;
while(aux != base){
printf(" -> %d \n",aux -> dados);
aux = aux -> ant;
}
Fernando Mira da Silva

Programacao
LEE
DEEC - IST

25

Listas duplas e aneis

Fernando Mira da Silva

26

Você também pode gostar