I recently came across an interesting implementation of linked lists (not sure where unfortunately), where the Node
class implemented insert and delete methods. The following is the Node
class for a double linked list, but the same principles apply to a single linked list.
class Node protected attr_writer :prev, :next public attr_reader :value, :prev, :next def initialize(value) @value = value end def remove @prev.next = @next if @prev @next.prev = @prev if @next @next = @prev = nil end def insert_after(node) remove @next = node.next @next.prev = self if @next @prev = node node.next = self end end
I find this implementation interesting because I found it pretty universal. To start creating a list and processing it, no more than Node
is required.
head = Node.new(1) middle = Node.new(2) middle.insert_after(head) tail = Node.new(3) tail.insert_after(middle) middle.remove
In addition to this implementation, you can create a more advanced API that is pretty easy to understand. Below is a more complete version of LinkedList
or Deque
. The list itself is a subclass of Node
and links to the head and tail of the list.
class ListNode < Node protected :remove
And here's how to use it in practice:
Even better is the each
method, which allows us to use any Enumerable function to search and iterate through nodes:
list = ListNode.new list.add_to_head(Node.new(1)) list.add_to_head(Node.new(2)) list.add_to_head(Node.new(3)) list.add_to_head(Node.new(4)) # list each value list.each {|node| puts node.value } # select all nodes with values greater than 2 list.each.select {|node| node.value > 2 } # find the first node with a value of 4 list.each.find {|node| node.value == 4 }
source share