Filas Denise Guliato Faculdade de Computao UFU www

  • Slides: 58
Download presentation
Filas Denise Guliato Faculdade de Computação – UFU www. facom. ufu. br/~guliato Vários slides

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

Pilhas e filas Filas

Filas Início Exclusões e Consultas Operações válidas: • Criar uma fila vazia • Inserir

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

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á

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

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

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

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

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

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

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 implementadas por contiguidade física

Filas implementadas por contiguidade física

Fila por contiguidade Fila implementada sobre arranjo Exclusões e Consultas Inserções IF FILA 0

Fila por contiguidade Fila implementada sobre arranjo Exclusões e Consultas Inserções IF FILA 0 1 2 3 4 5 6 7 FF 8 9 10 IF : início da fila FF : final da fila LS : limite superior da área (MAX_FILA-1) 12 13 14 LS 15 Fila vazia (? ) IF = FF = 0

Evolução da Fila por contiguidade LI=IF=FF FILA LI=IF 1. 2. 3. 4. 5. Inicializar

Evolução da Fila por contiguidade 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 LS 3 7 LI IF 7 FF LS 5 5

Fila por contiguidade Evolução da Fila (cont. ) LI 0 FILA LI 0 1.

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

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 1 2 3 IF 4 5 6 7 8 9 10 12 LS = FF 13 FILA LI ==FF 0 1 2 3 4 IF 5 LS 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

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

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

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

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

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

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

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

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

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)

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)

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

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 LI 0 IF 1 2 3 4 5 FF 6 7 8 9 10 11 LS 12 FILA LI 0 1 2 3 4 IF 5 6 7 8 9 10 FILA N=7 11 LS = FF 12

Algoritmo: Inserir nodo na fla Fila* Insere_fila(Fila *Ptf, int elem) -solução 2 Fila* Insere_fila(Fila*

Algoritmo: Inserir nodo na fla Fila* Insere_fila(Fila *Ptf, int elem) -solução 2 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

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 LI 0 1 2 IF 3 4 5 6 7 8 9 10 FF LS 11 12 FILA LI 0 1 2 3 FILA N=5 4 5 IF 6 7 8 9 10 11 12

Algoritmo: Remove nodo da fila Fila* Remove_fila(Fila *Ptp, int *elem) –solução 2 Fila* Remove_fila(Fila*

Algoritmo: Remove nodo da fila Fila* Remove_fila(Fila *Ptp, int *elem) –solução 2 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: Consultar Fila implementada sobre Fila por contiguidade Arranjo (solução 2) int Consulta_fila(Fila *Ptf,

Algoritmo: Consultar Fila implementada sobre Fila por contiguidade Arranjo (solução 2) 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

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

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 Ptf; Ptf = (Fila*)

Algoritmo: Criar Fila com alocação estática 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)

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)

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

Fila por contiguidade Inserção de um nodo de uma fila Solução 1 • Nodo inserido sempre no final da fila LI 0 1 2 3 4 IF 5 6 7 8 9 10 FF 12 LS 13 14 FILA LI 0 FILA 1 2 3 4 IF 5 6 7 8 9 10 FF LS 12 13 14

Algoritmo: Inserir nodo na fila (solução 1) int Insere_fila(Fila Ptf, int elem) Fila* Insere_fila(Fila*

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

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 1 2 3 IF 4 5 6 7 8 9 FF 10 LS 11 12 FILA LI 0 FILA 1 2 3 4 IF 5 FF 6 7 8 9 10 LS 11 12

Algoritmo: Remove nodo na fila Fila* Remove_fila(Fila *Ptf, int *elem) –solução 1 Fila* Remove_fila(Fila*

Algoritmo: Remove nodo na fila Fila* Remove_fila(Fila *Ptf, int *elem) –solução 1 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

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: Consultar Fila implementada sobre Fila por contiguidade Arranjo (solução 1) int Consulta_fila(Fila Ptf,

Algoritmo: Consultar Fila implementada sobre Fila por contiguidade Arranjo (solução 1) 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) { if (Ptf ==

Algoritmo: Liberar área alocada para a fila Fila* Libera_fila(Fila *Ptf) { if (Ptf == NULL) return Ptl; free(Ptf); return NULL; }

Filas implementadas por encadeamento

Filas implementadas por encadeamento

Filas por encadeamento Filas implementadas por encadeamento Inicio Exclusões e Consultas Final struct no{

Filas por encadeamento Filas implementadas por encadeamento Inicio Exclusões e Consultas Final struct no{ int info; struct no* prox; Inserções }; Pt. Fila Info F 1 F 2 prox F 3 Fn Para acessar o último nodo, é necessário percorrer toda a fila a partir do primeiro nodo

Filas por encadeamento com descritor Descritor Tipo de dados para o descritor da fila:

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; Pt. DF Prim Ult L 1 L 2 L 3 L 4

Operações sobre Filas por encadeamento implementadas por encadeamento com descritor • Criar uma fila

Operações sobre 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 •

Filas por encadeamento Criação da fila encadeada • Alocar o descritor da fila • Descritor inicializado em endereços nulos • Fila vazia Pt. DF Prim Ult

Algoritmo: Filas por encadeamento Criar Fila Encadeada endereçada por descritor Fila* Cria_fila(void) Fila* Cria_Fila(void)

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 Pt. DFila Prim Ult

Filas por encadeamento Inserção de um nodo na fila encadeada Pt. DFila Prim Ult / Pt. DFila Prim Ult

Filas por encadeamento Algoritmo: Inserir novo nodo em Fila Encadeada endereçada Algoritmo: por descritor

Filas por encadeamento Algoritmo: Inserir novo nodo em Fila Encadeada endereçada Algoritmo: 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 Pt. DFila Prim Ult

Filas por encadeamento Remoção de um nodo de fila encadeada Pt. DFila Prim Ult Pt. DFila / Pt. DFila Prim Ult / Pt. DFila / Prim Ult

Algoritmo: Filas por encadeamento Remover um nodo de Fila Encadeada endereçada por descritor Fila*

Algoritmo: Filas por encadeamento Remover um nodo de Fila Encadeada endereçada por descritor 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

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 Pt. DFila ? Prim Ult /

Algoritmo: Filas por encadeamento Consultar Fila Encadeada endereçada por descritor int Consulta_fila(Fila *Ptf) int

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 Pt. DFila Prim Ult Liberar posições ocupadas

Filas por encadeamento Destruição de fila encadeada Pt. DFila Prim Ult Liberar posições ocupadas pela lista / Pt. DFila Prim Ult Pt. DFila = nulo Liberar descritor

Algoritmo: Filas por encadeamento Destruir Fila Encadeada endereçada por descritor Fila* Libera_fila(Fila *Ptf) {

Algoritmo: Filas por encadeamento Destruir Fila Encadeada endereçada por descritor 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; }