LISTA DOBLEMENTE ENLAZADA - JAVA ☕
Las listas doblemente enlazadas son una estructura de datos lineal que consisten en una colección de nodos que están conectados en ambas direcciones. Cada nodo tiene un enlace anterior y un enlace siguiente, lo que permite una navegación bidireccional de la lista. En este artículo, discutiremos cómo crear una clase Nodo para implementar listas doblemente enlazadas en Java.
REPOSITORIO EN GITHUB - ESTRUCTURA DE DATOS
de los productos que ofrece en una lista doble enlace. Para la
implementación, tenga en cuenta las siguientes indicaciones:
o Mostrar todos los productos.
o Comprar productos (modifica el atributo cantidad
vendida).
o Productos con cantidad_bodega en cero.
o Productos más vendidos.
o Productos menos vendidos.
o Total de ventas en el día.
NOTA: Para la validación de la implementación de la tarea, es necesario registrar al menos 10 productos. Por otro lado, los criterios para la evaluación de la tarea serán:
implementación de la lista doble con los objetos “producto”, registrar mínimo 10 productos, generación del menú, ejecución de todos los puntos solicitados y entrega a tiempo.
Lo primero que haremos es crear una clase Nodo, la cual se va a encargar de hacer los enlaces en ambas direcciones, para ello se establecen los atributos necesarios, tales como Object dato (hace referencia al tipo de dato que se va a almacenar en la lista, Nodo siguiente (hace referencia al nodo siguiente) y Nodo anterior (hace referencia al nodo que está antes).
Clase Nodo
package Listas.ListaDoble;
public class Nodo {
private Object dato;
private Nodo siguiente;
private Nodo anterior;
// este contructor sirve para agregar al final o al inicio
public Nodo(Object dato, Nodo siguiente, Nodo anterior) {
this.dato = dato;
this.siguiente = siguiente;
this.anterior = anterior;
}
public Object getDato() {
return dato;
}
public void setDato(Object dato) {
this.dato = dato;
}
public Nodo getSiguiente() {
return siguiente;
}
public void setSiguiente(Nodo siguiente) {
this.siguiente = siguiente;
}
public Nodo getAnterior() {
return anterior;
}
public void setAnterior(Nodo anterior) {
this.anterior = anterior;
}
}
Una vez tengamos la clase Nodo, vamos a necesitar crear la clase ListaDoble, en la cual colocaremos las funciones o métodos que realiza una lista, tales como agregar, eliminar, mostrar etc.
Clase Lista
package Listas.ListaDoble;
public class Lista {
private Nodo inicio;
private Nodo fin;
private int cantidad;
public Lista() {
this.inicio = null;
this.fin = null;
this.cantidad = 0;
}
public boolean vacia() {
return inicio == null && fin == null;
}
public void agregarInicio(Object dato) {
if (vacia()) {
inicio = fin = new Nodo(dato, null, null);
} else {
Nodo nuevo = new Nodo(dato, inicio, null);
inicio.setAnterior(nuevo);
inicio = nuevo;
}
cantidad++;
}
public void agregarFin(Object dato) {
if (vacia()) {
inicio = fin = new Nodo(dato, null, null);
} else {
Nodo nuevo = new Nodo(dato, null, fin);
fin.setSiguiente(nuevo);
fin = nuevo;
}
cantidad++;
}
public boolean palabraPalindroma() {
if (!vacia()) {
int mitad = (int) (this.getCantidad() / 2);
int i = 0;
Nodo primero = inicio;
Nodo ultimo = fin;
while (i < mitad) {
if (primero.getDato() == ultimo.getDato()) {
primero = primero.getSiguiente();
ultimo = ultimo.getAnterior();
} else {
return false;
}
i++;
}
return true;
}
return false;
}
// para buscar un elemento
public boolean buscar(Object dato) {
if (!vacia()) {
Nodo aux = inicio;
while (aux != null) {
//verifica si el objeto que entra por parametro es de la misma clase
//y si es el elemento que se está buscando
if (dato.getClass().equals(aux.getDato().getClass()) && dato.equals(aux.getDato())) {
return true;
}
aux = aux.getSiguiente();
}
}
return false;
}
public void venderProducto(int codigo) {
Producto aVender = buscarProducto(codigo);
if (aVender != null) {
aVender.vender();
}
}
public Lista cantidadBodegaCero() {
Producto producto = null;
if (!vacia()) {
Lista salida = new Lista();
Nodo aux = inicio;
while (aux != null) {
//verifica si el objeto que entra por parametro es de la misma clase
//y si es el elemento que se está buscando
if (aux.getDato() instanceof Producto) {
producto = (Producto) (aux.getDato());
if (producto.getCantidadBodega() == 0) {
salida.agregarFin(producto);
}
}
aux = aux.getSiguiente();
}
return salida;
}
return null;
}
public Lista masVendidos() {
if (!vacia()) {
Lista salida = new Lista();
Nodo aux = inicio;
int valorMax = 0;
while (aux != null) {
if (aux.getDato() instanceof Producto) {
Producto productoAux = (Producto) (aux.getDato());
if (productoAux.getCantidadVendida() > valorMax) {
valorMax = productoAux.getCantidadVendida();
salida.agregarInicio(productoAux);
} else {
salida.agregarFin(productoAux);
}
}
aux = aux.getSiguiente();
}
return salida;
}
return null;
}
public Producto buscarProducto(int codigo) {
Producto salida = null;
if (!vacia()) {
Nodo aux = inicio;
while (aux != null) {
//verifica si el objeto que entra por parametro es de la misma clase
//y si es el elemento que se está buscando
if (aux.getDato() instanceof Producto) {
salida = (Producto) (aux.getDato());
if (salida.getCodigo() == codigo) {
return salida;
}
}
aux = aux.getSiguiente();
}
}
return salida;
}
//Para eliminar el inicio
public void eliminarInicio() {
if (!vacia()) {
if (inicio == fin) {
inicio = fin = null;
} else {
inicio = inicio.getSiguiente();
inicio.setAnterior(null);
}
cantidad--;
}
}
//para eliminar el fin
public void eliminarFin() {
if (!vacia()) {
if (inicio == fin) {
inicio = fin = null;
} else {
fin = fin.getAnterior();
fin.setSiguiente(null);
}
cantidad--;
}
}
//mostrar cada uno de los datos
public String mostrarFinInicio() {
String salida = "";
if (!vacia()) {
Nodo aux = fin;
while (aux != null) {
salida += aux.getDato() + "\n";
aux = aux.getAnterior();
}
}
return salida;
}
public void insertarLista() {
Nodo primero = inicio;
Nodo ultimo = fin;
for (int i = 0; i < this.cantidad / 2; i++) {
Object aux = primero.getDato();
primero.setDato(ultimo.getDato());
ultimo.setDato(aux);
ultimo = ultimo.getAnterior();
primero = primero.getSiguiente();
}
}
public String mostrarInicioFin() {
String salida = "";
if (!vacia()) {
Nodo aux = inicio;
while (aux != null) {
salida += aux.getDato() + "\n";
aux = aux.getSiguiente();
}
}
return salida;
}
public Nodo getInicio() {
return inicio;
}
public void setInicio(Nodo inicio) {
this.inicio = inicio;
}
public Nodo getFin() {
return fin;
}
public void setFin(Nodo fin) {
this.fin = fin;
}
public int getCantidad() {
return cantidad;
}
public void setCantidad(int cantidad) {
this.cantidad = cantidad;
}
}
Cuando tengamos esto, vamos a observar que hay algunos métodos que no son propios de la clase, tales como palabraPalindroma(), venderProducto(int codigo), cantidadBodegaCero(), masVendidos() y buscarProducto(int codigo) ya que estos métodos son algunos ejercicios que se realizaron en mi curso disponible en YouTube, pero para que funcione correctamente tienen que crear las siguientes clases también para que puedan usar los métodos correspondientes a los ejercicios.
Clase Producto
package Listas.ListaDoble;
public class Producto {
private int codigo;
private String nombre;
private double precioUnitario;
private int cantidadBodega;
private int cantidadVendida;
public Producto(int codigo, String nombre, double precioUnitario, int cantidadBodega) {
this.codigo = codigo;
this.nombre = nombre;
this.precioUnitario = precioUnitario;
this.cantidadBodega = cantidadBodega;
this.cantidadVendida = 0;
}
@Override
public String toString() {
return "Producto{" + "codigo=" + codigo + ", nombre=" + nombre + ", precioUnitario=" + precioUnitario + ", cantidadBodega=" + cantidadBodega + ", cantidadVendida=" + cantidadVendida + '}';
}
public boolean vender() {
if (this.getCantidadBodega() > 0) {
this.cantidadBodega--;
this.cantidadVendida++;
return true;
}
return false;
}
public int getCodigo() {
return codigo;
}
public void setCodigo(int codigo) {
this.codigo = codigo;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public double getPrecioUnitario() {
return precioUnitario;
}
public void setPrecioUnitario(double precioUnitario) {
this.precioUnitario = precioUnitario;
}
public int getCantidadBodega() {
return cantidadBodega;
}
public void setCantidadBodega(int cantidadBodega) {
this.cantidadBodega = cantidadBodega;
}
public int getCantidadVendida() {
return cantidadVendida;
}
public void setCantidadVendida(int cantidadVendida) {
this.cantidadVendida = cantidadVendida;
}
}
Esta clase Producto solo se usa para ser el objeto que se va a estar almacenando en la lista doble, para poder ejecutar y verificar tenemos que crear la clase Main, en la que creamos la lista y le damos vida.
Clase Main
package Listas.ListaDoble;
public class Main {
public static void main(String[] args) {
//ejercicio-> saber si una palabra
Lista lista = new Lista();
String palabra = "aibofobia";
for (int i = 0; i < palabra.length(); i++) {
lista.agregarFin(palabra.charAt(i));
}
System.out.println(lista.mostrarInicioFin());
System.out.println(lista.palabraPalindroma());
//Ejercicio-> invertir una lista
Lista invertir = new Lista();
invertir.agregarFin(3);
invertir.agregarFin(4);
invertir.agregarFin(7);
invertir.agregarFin(8);
invertir.agregarFin(9);
System.out.println(invertir.mostrarInicioFin());
invertir.insertarLista();
System.out.println(invertir.mostrarInicioFin());
}
}
Ahora para practicar se deja el siguiente ejercicio, la solución está implementada en las clase Lista, pero también es necesaria otra Clase Main en la que se haga un menú.
TIENDA MERCA MERCA
La tienda “MERCA MERCA” requiere registrar las ventas de cada unode los productos que ofrece en una lista doble enlace. Para la
implementación, tenga en cuenta las siguientes indicaciones:
- La lista doble enlace contiene objetos denominados “producto” y tendrá como atributos: código, nombre, precio unitario, cantidad_bodega y cantidad_vendida. Este último atributo debe iniciar en cero antes de realizar alguna compra.
- Implemente un menú en el cual se realicen las siguientes acciones:
o Mostrar todos los productos.
o Comprar productos (modifica el atributo cantidad
vendida).
o Productos con cantidad_bodega en cero.
o Productos más vendidos.
o Productos menos vendidos.
o Total de ventas en el día.
NOTA: Para la validación de la implementación de la tarea, es necesario registrar al menos 10 productos. Por otro lado, los criterios para la evaluación de la tarea serán:
implementación de la lista doble con los objetos “producto”, registrar mínimo 10 productos, generación del menú, ejecución de todos los puntos solicitados y entrega a tiempo.
Clase EjercicioMercaMerca
package Listas.ListaDoble;
import java.util.Scanner;
public class EjercicioMercaMerca {
public static void main(String[] args) {
Lista mercaMerca = new Lista();
int codigo = 0;
String nombre = "";
double precioUnitario = 0;
int cantidadBodega = 0;
int opcion;
Scanner en = new Scanner(System.in);
do {
System.out.println("1. Registrar nuevo producto");
System.out.println("2. Registrar productos aleatorios");
System.out.println("3. Mostrar todos los productos");
System.out.println("4. Comprar productos");
System.out.println("5. Productos con cantidad enBodega en cero");
System.out.println("6. Productos mas vendidos");
System.out.println("7. Salir");
System.out.print("Ingrese una opcion: ");
opcion = en.nextInt();
switch (opcion) {
case 1 -> {
System.out.println("codigo");
codigo = en.nextInt();
System.out.println("nombre");
nombre = en.next();
System.out.println("precio");
precioUnitario = en.nextDouble();
System.out.println("cant. Bodega");
cantidadBodega = en.nextInt();
mercaMerca.agregarFin(new Producto(codigo, nombre, precioUnitario, cantidadBodega));
}
case 2 -> {
System.out.println("cantidad a generar");
int cantidad = en.nextInt();
for (int i = 0; i < cantidad; i++) {
mercaMerca.agregarFin(new Producto(i, "P" + i, (Math.random() * 2000), (int) (Math.random() * 15)));
}
}
case 3 -> System.out.println(mercaMerca.mostrarInicioFin());
case 4 -> {
System.out.println("\n Ingrese el codigo del producto");
codigo = en.nextInt();
mercaMerca.venderProducto(codigo);
}
case 5 -> {
System.out.println("\n");
Lista bodegaCero = mercaMerca.cantidadBodegaCero();
System.out.println(bodegaCero.mostrarInicioFin());
}
case 6 -> {
System.out.println("\n");
Lista masVentas = mercaMerca.masVendidos();
System.out.println(masVentas.mostrarInicioFin());
}
case 7 -> System.out.println(" ha salido");
default -> System.out.println("Accion no valida");
}
} while (opcion != 7);
}
}