Got everything, just need to change comments and do the menu
This commit is contained in:
352
include/linkedlist.h
Normal file
352
include/linkedlist.h
Normal 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
14
include/utils.h
Normal 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 // !
|
||||
Reference in New Issue
Block a user