module Alimento # Clase nodo, almacena un valor y apunta al nodo anterior y al siguiente. Es necesaria para la clase Dll Nodo = Struct.new(:value, :next, :prev) class Nodo # Operador de salida de la clase nodo. Imprime únicamente el valor del nodo def to_s value.to_s end end class Dll include Enumerable attr_reader :head, :tail # Crea una lista doblemente enlazada. # Si toma un nodo de argumento apunta la cabeza y cola al mismo, # si no, la crea vacía. def initialize( nodo = nil ) @head = nodo @tail = nodo end # Inserta el valor al inicio de la lista def insertarDelante(valor) nodo = Nodo.new(valor,nil,nil) if @head == nil @head = nodo @tail = nodo else nodo.next = @head @head.prev = nodo @head = nodo end end # Inserta el valor al final de la lista def insertarDetras(valor) nodo = Nodo.new(valor,nil,nil) if @tail == nil @head = nodo @tail = nodo else nodo.prev = @tail @tail.next = nodo @tail = nodo end end # Elimina de la lista el último valor def extraerUltimo if @tail != nil @tail = @tail.prev @tail.next = nil end end # Elimina de la lista el primer valor def extraerPrimero if @head != nil @head = @head.next @head.prev = nil end end # Busca el primer nodo con el valor especificado y se elimina def extraer(nodo) if nodo == @head extraerPrimero elsif nodo == @tail extraerUltimo else tmp = @head while tmp != nodo tmp = tmp.next end if tmp == nodo tmp.prev.next = tmp.next tmp.next.prev = tmp.prev tmp.prev == nil tmp.next == nil end end end # Operador de salida de la Lista Doblemente enlazada def to_s if @head != nil temp = @head temp.value.to_s while temp.next != nil temp = temp.next temp.value.to_s end end end # Incluido para poder utilizar los métodos mixin de Enumerable para # la Lista Doblemente Enlazada. def each tmp = self.head while tmp != nil yield tmp.value tmp = tmp.next end end end end