Slide 1 - Facom

Propaganda
Filas
Denise Guliato
Faculdade de Computação – UFU
www.facom.ufu.br/~guliato
Vários slides foram adaptados de Nina Edelwais e Renata Galante
Estrutura de Dados – Série de Livros Didáticos - Informática - UFRGS
Pilhas e filas
Filas
Filas
Filas
Início
Exclusões
e
Consultas
Operações válidas:
• Criar uma fila vazia
• Inserir um nodo no final da fila
• Excluir o nodo do início da fila
• Consultar
• Destruir a fila
Final
Inserções
TAD Fila
Dados: numeros inteiros
Operações:
E_cheia
entrada: o endereço da fila
processo: verifica se a fila esta na condição de
cheia
saida: 1 se cheia, 0 caso contrário
TAD Fila
E_vazia
entrada: o endereço da fila
processo: verifica se a fila está na condição de
vazia
saida: 1 se vazia, 0 caso contrario
TAD Fila
Cria_fila
entrada: nenhuma
processo: aloca área para a fila e a coloca na
condição de vazia
saida: endereço da fila
TAD Fila
Insere_fila
entrada: endereço da fila e o elemento
processo: insere elemento no final da fila e
atualiza a fila
saida: endereço da fila
TAD Fila
Remove_fila
entrada: endereço da fila, endereço da variável
que contém a informação do nodo removido
processo: remove elemento do inicio da fila e
atualiza fila. Atualiza a variável de entrada.
saida: endereço da fila
TAD Fila
Consulta_fila
entrada: o endereço da fila e o endereço da
variável que recebe o resultado da consulta;
processo: consulta o inicio da fila, atualizando
a variável passada como parâmetro;
saida: 1 se sucesso e 0 se fracasso (fila vazia ou
inexistente).
TAD Fila
Libera_fila
entrada: o endereço da fila
processo: libera toda area alocada para a fila
saida: o endereço da fila
TAD Fila
Imprime_fila
Entrada: o endereço da fila
Processo: percorre a fila e imprime os elementos
Saida: 1 se sucesso; 0 se fracasso (fila inexistente)
Filas
Filas implementadas
por contiguidade
física
Fila por contiguidade
Fila implementada sobre arranjo
Exclusões
e
Consultas
Inserções
IF
0 1
FF
2
3
4
5
6
7
8
9
10
12 13 14
LS
15
FILA
IF : início da fila
FF : final da fila
LS : limite superior da área (MAX_FILA-1)
Fila vazia (?)
IF = FF = 0
Fila por contiguidade
Evolução da Fila
LI=IF=FF
FILA
LI=IF
1.
2.
3.
4.
5.
Inicializar a fila
Inserir um novo nodo com valor 3
Inserir um novo nodo com valor 7
Inserir um novo nodo com valor 5
Remover um nodo
FILA
LS
FF
3
FF
LI=IF
FILA
3
7
LI=IF
FILA
FILA
LS
3
7
LI
IF
7
FF
LS
FF
LS
5
5
Fila por contiguidade
Evolução da Fila (cont.)
LI
0
FILA
LI
0
1.
2.
3.
4.
5.
6.
7.
8.
9.
Inicializa a fia
Inserir um novo nodo com valor 3
Inserir um novo nodo com valor 7
Inserir um novo nodo com valor 5
Remover um nodo
Remover um nodo
Inserir um novo nodo com valor 8
Inserir um novo nodo com valor 4
Inserir um novo nodo com valor 1
2
7
5
1
IF
2
LI
0
1
FILA
LI
0
1
FILA
LI
0
FILA
3
4
LS
5
FF
3
4
LS
5
IF
2
3
FF
4
LS
5
5
8
IF
2
3
4
5
8
4
IF
2
3
4
LS
5
5
8
4
1
5
FILA
9. Inserir um novo nodo com valor 6
E AGORA ?
IF
1
1
FF=LS
5
FF
Fila por contiguidade
Ocupação circular do arranjo
IF
LI
0
LS
FF
1
2
3
4
5
6
7
8
9
10
12
13
FILA
LI
0
1
2
LS
FF
IF
3
4
5
6
7
8
9
10
12 13
FILA
LI
0
IF
1
2
3
4
LS = FF
5
6
7
8
9
10
12
13
FILA
LI ==FF
0
1
2
3
4
3
4
IF
5
LS
6
7
8
9
10
12
13
6
7
8
9
10
12 13
FILA
LI
0
FILA
1
FF
2
IF
5
LS
Ocupação circular do arranjo
LI
0
1
FF
2
3
4
IF
5
6
7
8
9
10
LS
12 13
FILA
LI
0
1
2
FF
3
4
IF
5
6
7
8
9
10
LS
12 13
FILA
LI
0
1
2
3
FF
4
IF
5
6
7
8
9
10
LS
12 13
FILA
LI
0
FILA
1
2
3
4
FF= IF
5
6
7
8
9
10
LS
12 13
Ocupação circular do arranjo
FILA VAZIA  IF==FF
LS
LI = IF = FF
0
1
2
3
4
5
6
7
8
9
10
12 13
FILA
FILA CHEIA  IF==FF
LI
0
1
2
3
4
FF= IF
5
6
7
8
9
FILA
COMO RESOLVER ESSE PROBLEMA??
10
LS
12 13
Algoritmo: Verifica se fila está cheia/vazia
Solução 1: desperdício de um nodo
LI
0
FF=LS
IF
1
2
3
4
5
6
7
8
9
10
12
13
FILA
Inicialização da fila: IF = 0 e FF = 0
Inserção: incrementa FF e insere
IF
aponta para um nodo vazio (nodo apontado
por IF será sempre vazio)
Fila cheia: se (FF+1)%MAX_FILA == IF
Fila vazia : se IF == FF
Tipo de dados utilizado para a fila com
alocação estática para solução 1
struct queue {
int fila[MAX_FILA];
int IF;
int FF;
};
typedef struct queue Fila;
Algoritmo: Verifica se fila está cheia/vazia
Solução 2: alterar o tipo de dados
struct queue {
int fila[MAX_FILA];
int IF;
int FF;
int N; //numro de elementos na fila
};
typedef struct queue Fila;
Inicialização da fila: IF = 0, FF = 0 e N=0
Inserção: insere em FF, atualiza FF e N
Fila cheia: se N == MAX_FILA
Fila vazia : se N == 0
Operações sobre Filas
Fila por contiguidade
implementadas por contiguidade física
• Criar uma fila vazia
• Inserir um nodo no final da fila
• Excluir o nodo do início da fila
• Consultar nodo no inicio da fila
•Liberar área alocada para a fila
•Verificar se fila está cheia
•Verificar se fila está vazia
Operações sobre Filas
implementadas por contiguidade física
SOLUÇÃO 2
struct queue {
int fila[MAX_FILA];
int IF;
int FF;
int N; //numro de elementos na fila
};
typedef struct queue Fila;
Inicialização da fila: IF = 0, FF = 0 e N=0
Inserção: insere em FF, atualiza FF e N
Fila cheia: se N == MAX_FILA
Fila vazia : se N == 0
Algoritmo: Criar Fila com alocação estática
Fila* Cria_fila(void) –solução 2
Fila* Cria_fila(void)
{
Fila *Ptf;
Ptf = (Fila*) malloc(sizeof(Fila));
if (Ptf != NULL)
{
Ptf->IF = 0;
Ptf->FF = 0;
Ptf ->N = 0;
}
return Ptf;
}
Algoritmo: Verifica se fila está cheia
int E_cheia(Fila *Ptf) –solução 2
int E_cheia(Fila *Ptf)
{
if (Ptf->N == MAX_FILA)
return 1;
else return 0;
}
Algoritmo: Verifica se fila está cheia
int E_vazia(Fila *Ptf) –solução 2
int E_vazia(Fila *Ptf)
{
if (Ptf->N == 0)
return 1;
else return 0;
}
Fila por contiguidade
Inserção de um nodo de uma fila
Solução 2
• Nodo inserido sempre no final da fila (insere e
atualiza FF)
N=6
IF
LI
0
1
2
3
4
5
FF
6
7
8
9
10
11
LS
12
FILA
IF
LI
0
1
2
3
4
5
LS = FF
6
7
8
9
10
FILA
N=7
11
12
Algoritmo: Inserir nodo na fla
Fila* Insere_fila(Fila *Ptf, int elem) -solução2
Fila* Insere_fila(Fila* Ptf, int elem)
{
if (Ptf == NULL || Ptf->N == MAX_FILA)
return Ptf;
Ptf->fila[Ptf->FF] = elem;
Ptf->FF = ( Ptf->FF+1)%MAX_FILA;
Ptf->N++;
return Ptf;
}
Fila por contiguidade
Remoção de um nodo de uma fila
Solução 2
• Nodo removido é sempre o do início da fila
Nodo que pode ser
removido
N=6
IF
LI
0
1
2
3
4
5
FF
6
7
8
9
10
LS
11 12
FILA
0
FF
IF
LI
1
2
3
FILA
N=5
4
5
6
7
8
9
10
LS
11 12
Algoritmo: Remove nodo da fila
Fila* Remove_fila(Fila *Ptp, int *elem) –solução2
Fila* Remove_fila(Fila* Ptf, int *elem)
{
if (Ptf == NULL || Ptf->N == 0 )
return Ptf;
*elem = Ptf->fila[Ptf->IF];
Ptf->IF= (Ptf)->IF+1)%MAX_FILA;
Ptf->N--;
return Ptf;
}
Algoritmo:
Fila por contiguidade
Consultar Fila implementada sobre
Arranjo (solução 2)
int Consulta_fila(Fila *Ptf, int *elem)
int Consulta_fila(Fila *Ptf, int *elem)
{
if (Ptf == NULL || Ptf->N == 0)
return 0;
*elem = (Ptf)->fila[Ptf->IF];
return 1;
}
Algoritmo: Liberar área alocada para a fila
Fila Libera_fila(Fila Ptf)
Ambas as soluções
Fila *Libera_fila(Fila *Ptf)
{
if (Ptf == NULL)
return Ptl;
free(Ptf);
return NULL;
}
Operações sobre Filas
implementadas por contiguidade física
SOLUÇÃO 1
Algoritmo: Criar Fila com alocação estática
Fila *Cria_fila(void)
Fila *Cria_fila(void)
{
Fila Ptf;
Ptf = (Fila*) malloc(sizeof(Fila));
if (Ptf != NULL)
{
Ptf->IF = 0;
Ptf->FF = 0;
}
return Ptf;
}
Algoritmo: Verifica se fila está cheia
int E_cheia(Fila *Ptf) –solução 1
int E_cheia(Fila *Ptf)
{
if ((Ptf->FF+1)%MAX_FILA == Ptf->IF)
return 1;
else return 0;
}
Algoritmo: Verifica se fila está cheia
int E_vazia(Fila *Ptf) –solução 1
int E_vazia(Fila *Ptf)
{
if (Ptf->IF == Ptf->FF)
return 1;
else return 0;
}
Fila por contiguidade
Inserção de um nodo de uma fila
Solução 1
• Nodo inserido sempre no final da fila
LI
0
IF
1
2
3
4
5
LS
FF
6
7
8
9
10
12
13 14
FILA
IF
LI
0
FILA
1
2
3
4
5
FF
6
7
8
9
10
LS
12 13 14
Algoritmo: Inserir nodo na fila (solução 1)
int Insere_fila(Fila Ptf, int elem)
Fila* Insere_fila(Fila* Ptf, int elem)
{
if ((Ptf->FF+1)%MAX_FILA) == Ptf->IF)
return Ptf;
Ptf->FF = (Ptf->FF+1)%MAX_FILA;
Ptf->fila[Ptf->FF] = elem;
return Ptf;
}
Fila por contiguidade
Remoção de um nodo de uma fila
Solução 1
• Nodo removido é sempre o do início da fila
Nodo que pode ser
removido
LI
0
IF
1
2
3
4
FF
5
6
7
8
9
10
LS
11 12
FILA
LI
0
FILA
FF
IF
1
2
3
4
5
6
7
8
9
10
LS
11 12
Algoritmo: Remove nodo na fila
Fila* Remove_fila(Fila *Ptf, int *elem) –solução1
Fila* Remove_fila(Fila* Ptf,int *elem)
{
if (Ptf->FF == Ptf->IF)
return Ptf; // fila vazia
Ptf->IF= (Ptf->IF+1)%MAX_FILA;
*elem = Ptf->fila[Ptf->IF];
return Ptf;
}
Fila por contiguidade
Acesso à fila –solução 1
• Só o nodo do início da fila pode ser acessado
• Acesso para consulta
Nodo que pode ser
acessado
LI
IF
FF
?
LS
Algoritmo:
Fila por contiguidade
Consultar Fila implementada sobre
Arranjo (solução 1)
int Consulta_fila(Fila Ptf, int *elem)
int Consulta_fila(Fila Ptf, int *elem)
{
if (Ptf->FF == Ptf->IF)
return 0; // fila vazia
*elem = Ptf->fila[Ptf->IF+1%MAX_FILA];
return 1;
}
Algoritmo: Liberar área alocada para a fila
Fila* Libera_fila(Fila *Ptf)
Fila* Libera_fila(Fila *Ptf)
{
if (Ptf == NULL)
return Ptl;
free(Ptf);
return NULL;
}
Filas
Filas implementadas
por encadeamento
Filas por encadeamento
Filas implementadas por encadeamento
Inicio
Exclusões
e
Consultas
Final
struct no{
int info;
struct no* prox;
};
Inserções
PtFila
Info
F1
F2
prox
F3
Fn
Para acessar o último nodo, é necessário percorrer toda a
fila a partir do primeiro nodo
Filas por encadeamento
Filas por encadeamento com descritor
Descritor
Tipo de dados para o descritor da fila:
Prim: primeiro da fila
Ult : último da fila
struct desc_q{
struct no* Prim;
struct no* Ult;
};
typedef struct desc_q Fila;
PtDF
Prim Ult
L1
L2
L3
L4
Operações sobre Filas
Filas por encadeamento
implementadas por encadeamento
com descritor
• Criar uma fila vazia
• Inserir um nodo no final da fila
• Excluir o nodo do início da fila
• Consultar / modificar nodo do início da fila
• Destruir a fila
Filas por encadeamento
Criação da fila encadeada
• Alocar o descritor da fila
• Descritor inicializado em endereços nulos
• Fila vazia
PtDF
Prim Ult
Algoritmo:
Filas por encadeamento
Criar Fila Encadeada endereçada por descritor
Fila* Cria_fila(void)
Fila* Cria_Fila(void)
{
Fila *Ptf;
Ptf = (Fila*) malloc (sizeof(Fila));
if (Ptf == NULL)
return NULL;
Ptf->Prim = NULL;
Ptf->Ult = NULL;
return Ptf;
}
Filas por encadeamento
Inserção de um nodo na fila encadeada
PtDFila
Prim Ult
PtDFila
Prim Ult
PtDFila
Prim Ult
/
PtDFila
Prim Ult
por encadeamento
Algoritmo:Inserir novo nodo em Fila EncadeadaFilas
endereçada
por descritor
Fila* Insere_Fila(Fila* Ptf, int elem)
Fila Insere_Fila(Fila* Ptf, int elem)
{
struct no *Pt;
Pt = (struct no*) malloc (sizeof(struct no));
if (Pt == NULL)
return Ptf;
Pt-> info = elem;
Pt->prox = NULL;
if (Ptf->Ult ==NULL) //fila vazia
Ptf->Prim = Pt;
else
Ptf->Ult->prox = Pt;
Ptf->Ult = Pt;
return Ptl;
}
Filas por encadeamento
Remoção de um nodo de fila encadeada
PtDFila
Prim Ult
PtDFila
/
PtDFila
Prim Ult
/
PtDFila
/
Prim Ult
Prim Ult
Algoritmo:
Filas por encadeamento
Remover um nodo de Fila Encadeada endereçada por
descritor
Fila* Remove_fila(Fila* Ptf, int elem)
Fila* Remove_fila(Fila* Ptf, int elem)
{
struct no*aux;
if ((*Ptf) == NULL) return 0;
if ((*Ptf)->Prim == NULL)
return 0; // fila vazia
*elem = (*Ptf)->Prim->info;
aux = (*Ptf)->Prim;
(*Ptf)->Prim = (*Ptf)->Prim->prox;
if ((*Ptf)->Prim == NULL)
(*Ptf)->Ult = NULL;
free(aux);
return 1;
}
Filas por encadeamento
Acesso a um nodo de fila encadeada
• Só o nodo do início da fila pode ser acessado
• Acessado diretamente pelo endereço no descritor
PtDFila
?
Prim Ult
/
Algoritmo:
Filas por encadeamento
Consultar Fila Encadeada endereçada por descritor
int Consulta_fila(Fila *Ptf)
int Consulta_fila(Fila *Ptf, int *elem)
{
If (Ptf == NULL)
return 0;
if (Ptf->Prim == NULL)
return 0; // fila vazia
*elem = Ptf->Prim->info;
return 1;
}
Filas por encadeamento
Destruição de fila encadeada
PtDFila
Prim Ult
Liberar posições
ocupadas pela lista
/
PtDFila
Prim Ult
PtDFila = nulo
Liberar descritor
Algoritmo:
Filas por encadeamento
Destruir Fila Encadeada endereçada por descritor
Fila* Libera_fila(Fila *Ptf)
Fila* Libera_fila(Fila *Ptf)
{
struct no* pt;
if (Ptf == NULL)
return NULL;
while (Ptf->Prim != NULL)
{
Pt = Ptf->Prim;
Ptf->Prim = Ptf->Prim ->prox
free(Pt);
}
free(Ptf);
return NULL;
}
Download