Got everything, just need to change comments and do the menu

This commit is contained in:
2026-03-21 22:13:19 -06:00
commit 96006ff170
8 changed files with 972 additions and 0 deletions

352
include/linkedlist.h Normal file
View File

@@ -0,0 +1,352 @@
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include <cstdlib>
#include <expected>
#include <new>
#include <print>
/**
* @brief Codigos de error para operaciones de LinkedList
*/
enum class LinkedListErr {
LINKEDLIST_OK, /**< Operacin exitosa */
LINKEDLIST_BAD_ALLOC, /**< Error al asignar memoria */
LINKEDLIST_OUT_OF_BOUNDS, /**< Índice fuera de rango */
LINKESLIST_INVALID_SIZE, /**< Tamaño inválido */
LINKEDLIST_NOT_FOUND, /**< Elemento no encontrado */
LINKEDLIST_EMPTY, /**< La lista está vacia */
};
/**
* @brief Nodo de una lista enlazada
*
* @tparam T Tipo de dato almacenado en el nodo
*/
template<typename T>
class Node {
public:
T data; /**< Dato almacenado en el nodo */
Node<T> *next; /**< Puntero al siguiente nodo */
};
/**
* @brief Implementación de una lista enlazada simple
*
* Estructura de datos dinamica que almacena elementos de tipo T
* utilizando nodos enlazados mediante punteros.
*
* @tparam T Tipo de dato almacenado en la lista
*/
template<typename T>
class LinkedList {
private:
size_t size; /**< Numero de elementos en la lista */
Node<T> *head; /**< Primer nodo de la lista */
Node<T> *tail; /**< Último nodo de la lista */
public:
/**
* @brief Constructor de la lista enlazada
*/
LinkedList();
/**
* @brief Destructor de la lista
*
* Libera toda la memoria de los nodos.
*/
~LinkedList();
/**
* @brief Obtiene el elemento en una posicion específica
*
* @param index indice del elemento
* @return std::expected<T, LinkedListErr> Valor encontrado o error
*/
std::expected<T, LinkedListErr> get(size_t index);
/**
* @brief Inserta un elemento al final de la lista
*
* @param value Valor a insertar
* @return LinkedListErr Cdigo de estado de la operacion
*/
LinkedListErr append(const T& value);
/**
* @brief Inserta un elemento al inicio de la lista
*
* @param value Valor a insertar
* @return LinkedListErr Codigo de estado
*/
LinkedListErr prepend(const T& value);
/**
* @brief Elimina y devuelve el ultimo elemento de la lista
*
* @return std::expected<T, LinkedListErr> Elemento eliminado o error
*/
std::expected<T, LinkedListErr> pop();
/**
* @brief Elimina el elemento en una posicion especifica
*
* @param index Indice del elemento a eliminar
* @return LinkedListErr Codigo de estado
*/
LinkedListErr remove(size_t index);
/**
* @brief Modifica el valor de un elemento en un indice
*
* @param index Índice del elemento
* @param value Nuevo valor
* @return LinkedListErr Código de estado
*/
LinkedListErr set(size_t index, const T& value);
/**
* @brief Busca un valor dentro de la lista
*
* @param value Valor a buscar
* @return std::expected<size_t, LinkedListErr> Índice del elemento o error
*/
std::expected<size_t, LinkedListErr> find(const T& value);
/**
* @brief Imprime los elementos de la lista
*
* @return LinkedListErr Código de estado
*/
LinkedListErr print();
/**
* @brief Verifica si la lista esta vacia
*
* @return true si la lista no contiene elementos
*/
bool is_empty();
/**
* @brief Obtiene el numero de elementos de la lista
*
* @return size_t Tamaño de la lista
*/
size_t len();
};
template <typename T>
LinkedList<T>::LinkedList() {
size = 0;
head = nullptr;
tail = nullptr;
}
template <typename T>
LinkedList<T>::~LinkedList() {
Node<T> *current = this->head;
while (current != nullptr) {
Node<T> *temp = current;
current = current->next;
delete temp;
}
}
template <typename T>
std::expected<T, LinkedListErr> LinkedList<T>::get(size_t index) {
if (index >= this->size) {
return std::unexpected(LinkedListErr::LINKEDLIST_OUT_OF_BOUNDS);
}
if (index == this->size - 1) {
return tail->data;
}
Node<T> *current = this->head;
for (size_t i = 0; i < index ; i++) {
current = current->next;
}
return current->data;
}
template <typename T>
LinkedListErr LinkedList<T>::set(size_t index, const T& val) {
if (index >= this->size) {
return LinkedListErr::LINKEDLIST_OUT_OF_BOUNDS;
}
if (index == this->size - 1) {
this->tail->data = val;
}
Node<T> *current = this->head;
for (size_t i = 0; i < index; i++) {
current = current->next;
}
current->data = val;
return LinkedListErr::LINKEDLIST_OK;
}
template <typename T>
LinkedListErr LinkedList<T>::append(const T& value) {
Node<T> *new_node = nullptr;
try {
new_node = new Node<T>;
} catch(std::bad_alloc&) {
return LinkedListErr::LINKEDLIST_BAD_ALLOC;
}
new_node->data = value;
new_node->next = nullptr;
if (this->head == nullptr && this->tail == nullptr) {
this->head = new_node;
this->tail = this->head;
} else {
this->tail->next = new_node;
this->tail = this->tail->next;
}
this->size += 1;
return LinkedListErr::LINKEDLIST_OK;
}
template <typename T>
LinkedListErr LinkedList<T>::prepend(const T& value) {
Node<T> *new_node = nullptr;
try {
new_node = new Node<T>;
} catch(std::bad_alloc&) {
return LinkedListErr::LINKEDLIST_BAD_ALLOC;
}
new_node->data = value;
new_node->next = nullptr;
if (this->head == nullptr && this->tail == nullptr) {
this->head = new_node;
this->tail = this->head;
} else {
new_node->next = this->head;
this->head = new_node;
}
this->size += 1;
return LinkedListErr::LINKEDLIST_OK;
}
template <typename T>
std::expected<T, LinkedListErr> LinkedList<T>::pop() {
if (this->size == 0) {
return std::unexpected(LinkedListErr::LINKEDLIST_EMPTY);
}
if (this->head->next == nullptr) {
T return_val = this->head->data;
delete this->head;
this->head = nullptr;
this->size--;
return return_val;
}
Node<T>* current = this->head;
while (current->next->next != nullptr) {
current = current->next;
}
T return_val = current->next->data;
delete current->next;
current->next = nullptr;
this->size--;
return return_val;
}
template <typename T>
LinkedListErr LinkedList<T>::remove(size_t index) {
if (index >= this->size) {
return LinkedListErr::LINKEDLIST_OUT_OF_BOUNDS;
}
if (index == 0) {
Node<T>* tmp = this->head;
this->head = this->head->next;
delete tmp;
this->size--;
return LinkedListErr::LINKEDLIST_OK;
}
Node<T>* current = this->head;
for (size_t i = 1; i < index; ++i) {
current = current->next;
}
Node<T>* tmp = current->next;
current->next = tmp->next;
if(tmp == this->tail) {
this->tail = current;
}
delete tmp;
this->size--;
return LinkedListErr::LINKEDLIST_OK;
}
template <typename T>
std::expected<size_t, LinkedListErr> LinkedList<T>::find(const T& value) {
Node<T> *current = this->head;
size_t count = 0;
while (current != nullptr) {
if (current->data == value) {
return count;
}
count++;
current = current->next;
}
return std::unexpected(LinkedListErr::LINKEDLIST_NOT_FOUND);
}
template <typename T>
LinkedListErr LinkedList<T>::print() {
if (this->size == 0) {
return LinkedListErr::LINKEDLIST_OK;
}
std::println("[LL]");
std::println(" |\n v");
Node<T> *current = this->head;
while (current != nullptr) {
std::println("Node({})", current->data);
std::println(" |");
std::println(" v");
current = current->next;
}
std::println("NULL");
return LinkedListErr::LINKEDLIST_OK;
}
template <typename T>
size_t LinkedList<T>::len() {
return this->size;
}
#endif // !

14
include/utils.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef UTILS_H
#define UTILS_H
#include <stddef.h>
#include <stdio.h>
void clear_screen();
void wait_enter();
void sleep_seconds(size_t s);
void read_string(const char *message, char **dest);
int read_int(const char *message, int *dest);
int read_double(const char *message, double *dest);
#endif // !