Skip to content

Instantly share code, notes, and snippets.

@aprescott
Created September 28, 2011 19:58
Show Gist options
  • Save aprescott/1249087 to your computer and use it in GitHub Desktop.
Save aprescott/1249087 to your computer and use it in GitHub Desktop.
Linked list reversal
class Node
attr_accessor :value, :next_element
def initialize(value, next_element = nil)
@value = value
@next_element = next_element
end
def to_s
return value.to_s if @next_element.nil?
"#{@value} -> #{@next_element.to_s}"
end
end
def reverse(list)
i = list
previous = nil
while i
next_element = i.next_element # temporary variable
i.next_element = previous
previous = i
i = next_element
# i.next_element, previous, i = previous, i, i.next_element
end
previous
end
list = Node.new(0, Node.new(1, Node.new(2)))
puts "#{list}
reversed is
#{reverse(list)}"
class Node
attr_accessor :value, :next_element
def initialize(value, next_element = nil)
@value = value
@next_element = next_element
end
def to_s
return value.to_s if @next_element.nil?
"#{@value} -> #{@next_element.to_s}"
end
end
# reverses A_0 -> A_1 -> ... -> A_{n-1} -> A_n -> nil
# to A_n -> A_{n-1} -> ... -> A_1 -> A_0 -> nil
#
# e.g., start with list = A -> B -> C -> nil
# begin with A -> nil and then move to B, setting
# B.next = A, creating B -> A -> nil, then move to C
# setting C.next = B. the next element in A -> B -> C -> nil
# is nil, so we stop.
def reverse(list)
# set the current node of the original list to the start.
# this variable tracks which node we're at in the original list.
i = list
previous = nil
# until we get to the end of the original list,
# set the next element of i to the previous node
# and move on to the next element, moving i and
# keeping track of the previous element.
#
# on the first run, previous == nil, i == A and
# then A.next = previous (== nil), starting us with
# A -> nil, and then i = B, previous = A.
#
# on the next iteration, B.next = previous (== A),
# giving us B -> A -> nil, and then i = C, and
# previous = B.
#
# on the penultimate iteration, C.next = previous (== B),
# giving us C -> B -> A -> nil, and then i = C.next (== nil),
# and previous = C.
#
# at this point, i == nil, so the condition is false,
# and we're done.
while i
next_element = i.next_element # temporary variable
i.next_element = previous
previous = i
i = next_element
# without a temp var:
# i.next_element, previous, i = previous, i, i.next_element
end
# since we've moved on to i == nil, and we need to
# start the list with C -> ..., return previous == C.
previous
end
list = Node.new(0, Node.new(1, Node.new(2)))
puts "#{list}
reversed is
#{reverse(list)}"
@aprescott
Copy link
Author

One slight problem with this is that after calling reverse(list), list is 0 -> nil, because of the i.next_element = previous assignment on the first iteration of the while loop when previous == nil, as part of the reversal.

list = Node.new(0, Node.new(1, Node.new(2)))
reverse(list)
list.to_s #=> "0"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment