Filas dinâmicas | Questões Resolvidas de Linguagem C

Filas dinâmicas | Questões Resolvidas de Linguagem C

·

9 min read

1.2- Filas dinâmicas

Implemente uma fila dinâmica contendo todas as funcionalidades de uma fila padrão. Para isso, resolvar:

a) Crie um nó padrão da fila.

b) Crie uma função de inicialização da fila vazia

c) Crie uma função push que cria e insere um novo nó para o final da fila.

d) Crie uma função pop que remove o primeiro elemento da fila.

e) Crie uma função de busca em que o usuário insere um valor (inteiro) e o programa retorna a sua posição na fila.

f) Crie uma função que percorre e imprime todos os elementos da fila.

_________________________________________

Situação no mundo da moda: Organização do backstage em um desfile de alta costura

Em um desfile de moda de alta costura, a organização do backstage é fundamental para garantir que todas as etapas ocorram de forma suave e eficiente. Uma das tarefas envolve a gestão das roupas e acessórios que serão utilizados pelos modelos. Nesse contexto, a implementação de uma fila dinâmica pode ser extremamente útil. Vamos explorar como cada uma das funcionalidades pode ser aplicada nessa situação:

a) Criação de um nó padrão da fila:

Para representar cada elemento da fila, podemos criar uma estrutura que armazene as informações da peça de roupa ou acessório, como nome, tipo, designer, e outras características relevantes.

typedef struct {
    char nome[50];
    char tipo[20];
    char designer[50];
    // Outras características relevantes
} PecaRoupa;

typedef struct No {
    PecaRoupa item;
    struct No* proximo;
} No;

b) Inicialização da fila vazia:

Antes do início do desfile, a equipe de backstage deve inicializar a fila vazia para receber as peças de roupa e acessórios que serão utilizados. Essa função garante que a fila esteja pronta para receber os elementos.

No* fila = NULL;

c) Função "adicionarItem" (push) para criar e inserir um novo nó no final da fila:

Conforme os modelos se preparam para entrar na passarela, a equipe de backstage utiliza a função "adicionarItem" para criar um novo nó representando a peça de roupa ou acessório e inseri-lo no final da fila. Essa função garante que todos os elementos sejam adicionados corretamente, mantendo a ordem de chegada.

void adicionarItem(PecaRoupa novoItem) {
    No* novoNo = (No*)malloc(sizeof(No));
    novoNo->item = novoItem;
    novoNo->proximo = NULL;

    if (fila == NULL) {
        fila = novoNo;
    } else {
        No* temp = fila;
        while (temp->proximo != NULL) {
            temp = temp->proximo;
        }
        temp->proximo = novoNo;
    }
}

d) Função "removerItem" (pop) para remover o primeiro elemento da fila:

Quando o modelo está pronto para entrar na passarela, a equipe de backstage utiliza a função "removerItem" para retirar o primeiro elemento da fila, liberando espaço para as próximas peças. Essa função também é responsável por liberar a memória do nó removido, evitando vazamentos de memória.

void removerItem() {
    if (fila == NULL) {
        printf("A fila está vazia. Não há peças de roupa para remover.\n");
        return;
    }

    No* temp = fila;
    fila = fila->proximo;
    free(temp);
}

e) Função "buscarItem" para buscar a posição de um valor específico na fila:

Caso seja necessário localizar uma peça de roupa ou acessório específico na fila, a equipe de backstage pode utilizar a função "buscarItem". Essa função permite que o usuário insira um valor (por exemplo, o nome da peça) e o programa retorna a posição dessa peça na fila, facilitando sua localização.

void buscarItem(char nomeItem[]) {
    int posicao = 0;
    No* temp = fila;

    while (temp != NULL) {
        if (strcmp(temp->item.nome, nomeItem) == 0) {
            printf("A peça de roupa '%s' está na posição %d da fila.\n", nomeItem, posicao);
            return;
        }
        posicao++;
        temp = temp->proximo;
    }

    printf("A peça de roupa '%s' não foi encontrada na fila.\n", nomeItem);
}

f) Função "imprimirFila" para percorrer e imprimir todos os elementos da fila:

A função "imprimirFila" permite que a equipe de backstage percorra a fila e imprima todas as informações das peças de roupa e acessórios. Isso ajuda a ter uma visão geral dos elementos presentes na fila e auxilia na organização e coordenação dos próximos passos do desfile.

void imprimirFila() {
    printf("Fila de peças de roupa:\n");
    No* temp = fila;

    while (temp != NULL) {
        printf("Nome: %s | Tipo: %s | Designer: %s\n", temp->item.nome, temp->item.tipo, temp->item.designer);
        temp = temp->proximo;
    }
}

Com a implementação da fila dinâmica e suas funcionalidades, a equipe de backstage consegue gerenciar de forma eficiente as peças de roupa e acessórios durante o desfile de alta costura. Isso contribui para um fluxo de trabalho organizado e garante que cada elemento seja utilizado no momento adequado, resultando em um evento de moda impecável e sofisticado.

  1. Implemente uma fila de números inteiros usando apenas arrays (vetores) de 100 posições. Nessa fila a posição zero [0] e posição um [1] são usadas para representar a posição inicial e final da fila respectivamente. O restante das posições [2] até [99] devem conter os elementos do vetor.

Para esse exercício você precisa:

  • Demonstre como inicializar esse vetor de modo a representar a fila vazia

  • Escreva a função desenfileira → remove elementos da fila;

  • Escreva a função enfileira → adiciona elementos a fila.

#include <stdio.h>

#define TAMANHO_FILA 100

int fila[TAMANHO_FILA];

int inicio = 0; // Posição inicial da fila
int fim = 1; // Posição final da fila

// Função para inicializar a fila vazia
void inicializarFila() {
    inicio = 0;
    fim = 1;
}

// Função para enfileirar (adicionar) elementos na fila
void enfileirar(int elemento) {
    if (fim == inicio) {
        printf("A fila está cheia. Não é possível adicionar mais elementos.\n");
        return;
    }

    fila[fim] = elemento;
    fim = (fim + 1) % TAMANHO_FILA; // Incrementa o fim circularmente
}

// Função para desenfileirar (remover) o primeiro elemento da fila
int desenfileirar() {
    if ((fim - inicio) == 1) {
        printf("A fila está vazia. Não há elementos para remover.\n");
        return -1; // Valor inválido para indicar erro
    }

    int elemento = fila[inicio];
    inicio = (inicio + 1) % TAMANHO_FILA; // Incrementa o início circularmente
    return elemento;
}

int main() {
    inicializarFila(); // Inicializa a fila vazia

    enfileirar(10);
    enfileirar(20);
    enfileirar(30);

    int elementoRemovido = desenfileirar();
    printf("Elemento removido: %d\n", elementoRemovido);

    return 0;
}
  • 3)Considere a fila estática e a fila dinâmica que foram implementadas nos exercícios anteriores e escreva uma função que inverta a ordem dos elementos da fila. Por exemplo:

[1] [4] [5] [2] → [2] [5] [4] [1]

Fila Estática

#define TAMANHO_FILA 100

int fila[TAMANHO_FILA];
int inicio = 0;
int fim = 0;

// Função para inverter a ordem dos elementos da fila
void inverterFilaEstatica() {
    int temp[TAMANHO_FILA]; // Vetor temporário para armazenar os elementos da fila invertidos
    int tamanho = 0; // Variável para controlar o tamanho atual da fila

    // Armazena os elementos da fila no vetor temporário na ordem inversa
    while (inicio != fim) {
        temp[tamanho] = fila[--fim];
        tamanho++;
    }

    // Copia os elementos do vetor temporário de volta para a fila original
    for (int i = 0; i < tamanho; i++) {
        fila[fim++] = temp[i];
    }
}

Fila Dinâmica

#include <stdlib.h>

typedef struct Node {
    int data;
    struct Node* next;
} Node;

Node* front = NULL;
Node* rear = NULL;

// Função para inverter a ordem dos elementos da fila
void inverterFilaDinamica() {
    Node* current = front;
    Node* prev = NULL;
    Node* next = NULL;

    // Inverte os ponteiros de next em cada nó
    while (current != NULL) {
        next = current->next;
        current->next = prev;
        prev = current;
        current = next;
    }

    // Atualiza os ponteiros front e rear
    rear = front;
    front = prev;
}
  1. Considerando a estrutura de fila dinâmica implementada anteriormente uma função para FurarFila. Essa função deverá inserir um item na primeira posição da fila. Lembre-se que nesse caso estamos desrespeitando o conceito de fila – primeiro a entrar é o primeiro a sair).
#include <stdio.h>
#include <stdlib.h>

typedef struct No {
    int dado;
    struct No* prox;
} No;

No* inicio = NULL;
No* fim = NULL;

// Função para inserir um item na primeira posição da fila
void furarFila(int item) {
    // Cria um novo nó
    No* novoNo = (No*)malloc(sizeof(No));
    novoNo->dado = item;
    novoNo->prox = NULL;

    // Se a fila estiver vazia, o novo nó se torna o início e o fim
    if (inicio == NULL) {
        inicio = novoNo;
        fim = novoNo;
    }
    // Caso contrário, o novo nó é inserido na primeira posição
    else {
        novoNo->prox = inicio;
        inicio = novoNo;
    }
}

// Função para imprimir a fila
void imprimirFila() {
    if (inicio == NULL) {
        printf("A fila está vazia.\n");
    } else {
        printf("Fila:\n");
        No* atual = inicio;
        while (atual != NULL) {
            printf("%d ", atual->dado);
            atual = atual->prox;
        }
        printf("\n");
    }
}

int main() {
    furarFila(1);
    furarFila(2);
    furarFila(3);

    imprimirFila();  // Saída: Fila: 3 2 1

    return 0;
}

___________________________________________________________

O Conceito de Filas Dinâmicas

As filas dinâmicas são estruturas de dados flexíveis, capazes de se adaptar ao tamanho das informações que estão sendo armazenadas. Ao contrário das filas estáticas, em que o tamanho é pré-definido, as filas dinâmicas permitem que novos elementos sejam adicionados e removidos conforme necessário, sem restrições de capacidade.

Implementação em Linguagem C

Na linguagem C, podemos implementar filas dinâmicas por meio de ponteiros e alocação dinâmica de memória. Vamos destacar as principais funções para criar uma fila dinâmica eficiente:

  1. Função enfileirar/ "enqueue" - Adicionar um elemento à fila: A função "enqueue" recebe um item como parâmetro e o insere no final da fila. Caso a fila esteja vazia, um novo nó é criado e se torna o primeiro elemento. Se a fila já contiver elementos, o novo nó é adicionado ao final, mantendo a ordem correta.
  1. Função desenfileirar / "dequeue" - Remover o primeiro elemento da fila: A função "dequeue" remove o primeiro elemento da fila, reposicionando os demais elementos. É importante liberar a memória do nó removido para evitar vazamentos de memória.
  1. Função estaVazia / "isEmpty" - Verificar se a fila está vazia: A função "isEmpty" verifica se a fila está vazia, retornando verdadeiro ou falso. Isso é útil para evitar operações inválidas, como remover elementos de uma fila vazia.
  1. Função imprimirFila / "printQueue" - Imprimir a fila na tela: A função "printQueue" percorre a fila e imprime os elementos armazenados. Isso permite visualizar facilmente os dados organizados na fila.
#include <stdio.h>
#include <stdlib.h>

// Definição da estrutura de cada nó da fila
typedef struct No {
    int dado;
    struct No* proximo;
} No;

// Função para adicionar um elemento ao final da fila
void enfileirar(No** fila, int item) {
    No* novoNo = (No*)malloc(sizeof(No));
    novoNo->dado = item;
    novoNo->proximo = NULL;

    if (*fila == NULL) {
        *fila = novoNo;
    } else {
        No* atual = *fila;
        while (atual->proximo != NULL) {
            atual = atual->proximo;
        }
        atual->proximo = novoNo;
    }

    printf("Elemento adicionado à fila com sucesso.\n");
}

// Função para remover o primeiro elemento da fila
void desenfileirar(No** fila) {
    if (*fila == NULL) {
        printf("A fila está vazia.\n");
        return;
    }

    No* primeiro = *fila;
    *fila = primeiro->proximo;
    free(primeiro);

    printf("Elemento removido da fila com sucesso.\n");
}

// Função para verificar se a fila está vazia
int estaVazia(No* fila) {
    return (fila == NULL);
}

// Função para imprimir a fila na tela
void imprimirFila(No* fila) {
    if (fila == NULL) {
        printf("A fila está vazia.\n");
        return;
    }

    printf("Fila: ");
    No* atual = fila;
    while (atual != NULL) {
        printf("%d ", atual->dado);
        atual = atual->proximo;
    }
    printf("\n");
}

int main() {
    No* fila = NULL;

    enfileirar(&fila, 10);
    enfileirar(&fila, 20);
    enfileirar(&fila, 30);

    imprimirFila(fila);

    desenfileirar(&fila);

    imprimirFila(fila);

    return 0;
}