Implemente uma pilha sobre uma lista dinâmica e encadeada que possa tanto empilhar inteiros quanto caracteres
Passo 1
A questão pede implementar uma pilha usando lista ligada dinâmica que aceite tanto inteiros quanto caracteres. O assunto é estrutura de dados (pilha) e vamos precisar de conhecimento em alocação dinâmica, structs, enum e union em C para distinguir e armazenar os dois tipos.
Passo 2
Primeiro, definimos um enum DataType para marcar se o nó guarda um inteiro ou um caractere. Em seguida, criamos a struct Node contendo esse enum, uma union com um int e um char, e um ponteiro para o próximo nó. Também criamos a struct Stack com um ponteiro para o topo.
Passo 3
Implementamos initStack para iniciar a pilha (com topo NULL) e isEmpty para verificar se não há elementos.
Passo 4
Para empilhar, criamos pushInt e pushChar. Cada uma aloca um novo nó, preenche o campo data correspondente, ajusta o ponteiro next para o antigo topo e atualiza o topo.
Passo 5
Para desempilhar, implementamos uma função pop genérica que retorna o tipo e o valor através de parâmetros de saída. A função faz a checagem de pilha vazia, lê o dado correto da union com base no enum, atualiza o topo e libera a memória do nó.
Passo 6
No main, mostramos um exemplo de uso: empilhamos inteiros e caracteres, e depois fazemos um laço de pop até a pilha ficar vazia, imprimindo cada valor de acordo com seu tipo.
Resposta
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdbool.h>
// Marca se o dado é inteiro ou caractere
typedef enum {
INT_TYPE,
CHAR_TYPE
} DataType;
typedef enum {
INT_TYPE,
CHAR_TYPE
} DataType;
// Nó da lista que armazena um inteiro ou caractere
typedef struct Node {
DataType type;
union {
int i;
char c;
} data;
struct Node* next;
} Node;
typedef struct Node {
DataType type;
union {
int i;
char c;
} data;
struct Node* next;
} Node;
// Pilha apontando para o topo
typedef struct {
Node* top;
} Stack;
typedef struct {
Node* top;
} Stack;
// Inicializa a pilha (vazia)
void initStack(Stack* s) {
s->top = NULL;
}
void initStack(Stack* s) {
s->top = NULL;
}
// Verifica se a pilha está vazia
bool isEmpty(Stack* s) {
return (s->top == NULL);
}
bool isEmpty(Stack* s) {
return (s->top == NULL);
}
// Empilha um inteiro
void pushInt(Stack* s, int value) {
Node* n = (Node*)malloc(sizeof(Node));
if (!n) exit(EXIT_FAILURE);
n->type = INT_TYPE;
n->data.i = value;
n->next = s->top;
s->top = n;
}
void pushInt(Stack* s, int value) {
Node* n = (Node*)malloc(sizeof(Node));
if (!n) exit(EXIT_FAILURE);
n->type = INT_TYPE;
n->data.i = value;
n->next = s->top;
s->top = n;
}
// Empilha um caractere
void pushChar(Stack* s, char value) {
Node* n = (Node*)malloc(sizeof(Node));
if (!n) exit(EXIT_FAILURE);
n->type = CHAR_TYPE;
n->data.c = value;
n->next = s->top;
s->top = n;
}
void pushChar(Stack* s, char value) {
Node* n = (Node*)malloc(sizeof(Node));
if (!n) exit(EXIT_FAILURE);
n->type = CHAR_TYPE;
n->data.c = value;
n->next = s->top;
s->top = n;
}
// Desempilha e retorna o tipo e valor através de ponteiros
bool pop(Stack* s, DataType* type, int* outInt, char* outChar) {
if (isEmpty(s)) return false;
Node* n = s->top;
*type = n->type;
if (n->type == INT_TYPE) {
*outInt = n->data.i;
} else {
*outChar = n->data.c;
}
s->top = n->next;
free(n);
return true;
}
bool pop(Stack* s, DataType* type, int* outInt, char* outChar) {
if (isEmpty(s)) return false;
Node* n = s->top;
*type = n->type;
if (n->type == INT_TYPE) {
*outInt = n->data.i;
} else {
*outChar = n->data.c;
}
s->top = n->next;
free(n);
return true;
}
int main() {
Stack s;
initStack(&s);
Stack s;
initStack(&s);
// Exemplo de uso
pushInt(&s, 10);
pushChar(&s, 'A');
pushInt(&s, 20);
DataType t;
int vi;
char vc;
while (pop(&s, &t, &vi, &vc)) {
if (t == INT_TYPE)
printf("Desempilhou inteiro: %d\n", vi);
else
printf("Desempilhou caractere: %c\n", vc);
}
return 0;
}