class Lista

Clase lista doblemente enlazada @author alu0100896282 @attr_reader [Node] head Primer nodo de la lista @attr_reader [Node] tail Último nodo de la lista

Constants

Node

Nodo de la lista @author alu0100896282 @attr [Object] value Contenido del nodo @attr [Node] next Nodo siguiente @attr [Node] prev Nodo anterior

Attributes

head[R]
tail[R]

Public Class Methods

new(*elementos) click to toggle source

Crea una instancia de la clase Lista @param [Argument list] elementos Elementos que insertar al final de la lista @return [Lista] Nueva instancia de la clase lista

# File lib/dieta/lista_m.rb, line 34
def initialize(*elementos)
    @head = nil
    @tail = nil
    @size = 0

    if elementos.size > 0
        push_last(*elementos)
    end
end

Public Instance Methods

[](index) click to toggle source

Accede un nodo de la lista @param [Number] index Índice del nodo @return [Node] Nodo de la lista

# File lib/dieta/lista_m.rb, line 89
def [] (index)

    # Si está fuera de rango, vuelve
    if (index>=@size or index<=(-@size)) then return nil end

    # Iterar desde el otro lado
    if (index<0     ) then index = @size+index end

    # Acanza hasta la posición
    current = @head;
    i = 0
    while i < index and current do
        current = current[:next]
        i+=1
    end

    current
end
each() { |current| ... } click to toggle source

Ejecuta un bloque de código para cada elemento

# File lib/dieta/lista_m.rb, line 23
def each
    current = @head;
    while current do
        yield(current[:value])
        current = current[:next]
    end
end
insert_after(index, element) click to toggle source

Inserta un elemento después del elemento con un índice determinado @param [Number] index Índice del elemento sobre el que insertar después @param [Object] element Elemento a insertar @return [Number] Tamaño de la lista

# File lib/dieta/lista_m.rb, line 148
def insert_after(index, element)

    prev_el = self[index]

    # Si no existe el elemento del índice, no insertes nada
    if !prev_el then return end

    next_el = prev_el[:next]
    new_el  = Node.new(element, next_el, prev_el)

    prev_el[:next] = new_el
    if next_el then next_el[:prev] = new_el else @tail = new_el end

    @size += 1
end
pop() click to toggle source

Extrae y elimina un elemento del principio de la lista @return [Object] Valor del nodo extraído

# File lib/dieta/lista_m.rb, line 110
def pop

    # Si la lista está vacía, devuelve nulo
    if !@head then return nil end

    # Extrae el primer nodo
    aux = @head
    @head = aux[:next]

    # Si la lista se queda vacía, fija tail a vacía, sino, fija el previo de head a nulo
    if !@head then @tail = nil else @head[:prev] = nil end

    @size -= 1
    aux[:value]
end
pop_last() click to toggle source

Extrae y elimina el último elemento de la lista @return [Object] Valor del nodo extraído

# File lib/dieta/lista_m.rb, line 128
def pop_last

    # Si la lista está vacía, devuelve nulo
    if !@head then return nil end

    # Extrae el ultimo nodo
    aux = @tail
    @tail = aux[:prev]

    # Si la lista se queda vacía, fija head a vacía, sino, fija el siguiente de tail a nulo
    if !@tail then @head = nil else @tail[:next] = nil end

    @size -= 1
    aux[:value]
end
push(*elementos) click to toggle source

Inserta un conjunto de elementos al principio @param [Argument list] elementos Elementos que insertar al principio @return [Number] Tamaño de la lista

# File lib/dieta/lista_m.rb, line 47
def push(*elementos)
    elementos.each do |elemento|

        # Nueva head
        newHead = Node.new(elemento, @head, nil)

        # Si la tail era nula, apunta a head
        if !@tail then @tail = newHead end

        # Si ya había head, su anterior será el nuevo head
        if @head then @head[:prev] = newHead end

        @head = newHead

    end
    @size += elementos.size # Devuelve el tamaño
end
push_last(*elementos) click to toggle source

Inserta un conjunto de elementos al final @param [Argument list] elementos Elementos que insertar al final @return [Number] Tamaño de la lista

# File lib/dieta/lista_m.rb, line 68
def push_last(*elementos)
    elementos.each do |elemento|

        # Nueva tail
        newTail = Node.new(elemento, nil, @tail)

        # Si la head era nula, apunta a head
        if !@head then @head = newTail end

        # Si ya había tail, su siguiente será el nuevo tail
        if @tail then @tail[:next] = newTail end

        @tail = newTail

    end
    @size += elementos.size # Devuelve el tamaño
end
to_s() click to toggle source

Transforma en una cadena @return [String] Cadena con los elementos de la lista

# File lib/dieta/lista_m.rb, line 166
def to_s
    result = ""
    current = @head;
    i = 0
    while current do
        result += "#{i+1}) " + current[:value].to_s + ", "
        current = current[:next]
        i+=1
    end
    result
end