Pilha
Uma pilha é uma lista onde as inserções e remoções são sempre feitas na mesma ponta. Desta forma, o item removido primeiro é o que foi inserido por último (LIFO - Last In First Out). As pilhas são úteis quando queremos armazenar temporariamente uma informação que vamos usar logo depois. Por exemplo, a maioria dos processadores utiliza uma pilha para armazenar os endereços de retorno de subrotinas, permitindo que subrotinas sejam chamadas dentro de subrotinas. Algorítmos recursivos (como o quicksort) também costumam usar pilhas.
É costume chamar a operação de inserção na pilha de Push e a inserção de remoção de Pop (na inserção estamos 'empurrando' um elemento no alto da pilha e na remoção o elemento no topo 'pula' para fora da pilha).
A implementação de uma pilha é muito simples. Temos um vetor de N posições para armazenar os elementos e um índice (ou ponteiro) para indicar o topo. Algumas variações são possíveis:
- Podemos empilhar os itens no sentido de índices (ou endereços) crescentes ou decrescentes.
- O índice do topo pode apontar para a posição de remoção ou para a posição de inserção.
Segue um exemplo de implementação em C, empilhando no sentido de índices crescentes e com o índice de topo apontando para a posição de inserção. Neste exemplo a pilha contém ponteiros e o valor NULL é usado para indicar underflow.
#define N 10 // número de elementos na pilha
void *pilha[N]; // a pilha
int topo = 0; // índice para o topo da pilha
// Coloca um elemento no topo da pilha
// Retorna FALSE se pilha cheia
int Push (void *elemento)
{
if (topo == N)
return FALSE;
pilha [topo++] = elemento
return TRUE;
}
// Retira o elemento no topo da pilha
// Retorna NULL se pilha vazia
void *Pop ()
{
if (topo == 0)
return NULL;
return pilha [--topo];
}
Fila
Uma fila é uma lista onde as inserções são sempre feitas em uma ponta e as remoções são sempre feitas na outra. Desta forma remove-se sempre o item mais antigo (FIFO - First In First Out). AS filas são úteis para sincronizar duas tarefas assíncronas, armazenado temporariamente dados produzidos por uma delas até serem consumidos pela outra.
Quando examinamos as listas genéricas sequenciais , verificamos que era preciso mover os elementos após uma inserção ou remoção. No caso específico da fila isto pode ser evitado implementando uma fila circular, na qual os ponteiros voltam ao início quando passam do final.
A forma mais convencional de implementar uma fila circular é ter um vetor de N+1 elementos e dois índices (ou ponteiros), um apontando para onde será feita a próxima inserção e outro apontando para onde será feita a próxima remoção. A fila vazia é indicada pela igualdade dos índices (ou ponteiros). Para não confundir fila cheia com fila vazia, deixa-se sempre pelo menos uma posição livre no vetor (daí ele ter N+1 posições para armazenar N elementos).
#define N 10 // número máximo de elementos na fila
void *fila [N+1]; // a fila
int iPoe = 0; // indice para onde inserir
int iTira = 0; // indice para onde retirar
// Coloca um elemento na fila
// Retorna FALSE se fila cheia
int Poe (void *elemento)
{
int aux;
// calcula o valor de pPoe após a inserção
aux = iPoe + 1;
if (aux > N)
aux = 0; // circula
// Testa fila cheia
if (aux == iTira)
return FALSE;
// Coloca na fila
fila [iPoe] = elemento
iPoe = aux;
}
// Retira elemento da fila
// Retorna NULL se fila vazia
void *Tira ()
{
void *aux;
// Testa fila vazia
if (iPoe == iTira)
return NULL;
// Pega o elemento a retirar
aux = fila [iTira];
// Avanca iTira
iTira = iTira + 1;
if (iTira > N)
iTira = 0; // circula
return aux;
}
iTira = (iTira+1) & 15;
7 comentários:
Ola,
Otimo post, me ajudou a entender os conceitos de pilha e fila.
Obrigado.
Tinha um trabalho a fazer e não havia entendido a explicação da professora, agora tudo entendido. Obrigado!!!
grande post.
sanou minhas duvidas a respeito de filas e pilhas.
abraço.
Obrigado!
O post foi de grande importância, pois
as explicações em sala dada pelo professor deixou algumas dúvidas.
Ficaram bem claras após ler e executar
estes exemplos.
ótimo post! era exatamente o conceito que eu estava tentando entender.
Ótimo post. Simples e completo, sem firulas. Me ajudou muito. Obrigado!
Liomar
Postar um comentário