在下面的变异示例中,我不明白链接列表是如何反转的。
class LinkedListNode
attr_accessor :value, :next_node
def initialize(value, next_node=nil)
@value = value
@next_node = next_node
end
end
def print_values(list_node)
print "#{list_node.value} --> "
if list_node.next_node.nil?
print "nil\n"
return
else
print_values(list_node.next_node)
end
end
def reverse_list(list, previous=nil)
current_head = list.next_node
list.next_node = previous
if current_head
reverse_list(current_head, list)
else
list
end
end
node1 = LinkedListNode.new(37)
node2 = LinkedListNode.new(99, node1)
node3 = LinkedListNode.new(12, node2)
print_values(node3)
puts "-------"
revlist = reverse_list(node3)
print_values(revlist)
如果我返回current_head
,我会得到99->37->nil
,这是有道理的,因为99
将是next_node
。返回下一行,
list.next_node = previous
引发错误,因为print_values
方法无法打印nil
的值。我不明白什么是逆转清单。如果有人能向我解释这一点,我将不胜感激。
答案 0 :(得分:5)
这是我编写的一点可视化。
^
指向列表的头部。在每个递归级别,其右箭头“转向”从右侧的元素指向左侧的元素。继续,直到有一个右箭头(指向非零)。如果右箭头指向nil,则返回当前头部。
previous
↓
nil 12 -> 99 -> 37 -> nil
^
previous
↓
nil <- 12 99 -> 37 -> nil
^
previous
↓
nil <- 12 <- 99 37 -> nil
^
nil <- 12 <- 99 <- 37
^
答案 1 :(得分:3)
# Create a LinkedListNode instance with value 36
node1 = LinkedListNode.new(37)
# Create a LinkedListNode instance which next value is node1
node2 = LinkedListNode.new(99, node1)
# node2 -> node1
# Create a LinkedListNode instance which next value is node2
node3 = LinkedListNode.new(12, node2)
# node3 -> node2 -> node1
print_values(node3)
# 12 -> 99 -> 37
拳头传递到reverse_list方法
reverse_list(node3)
def reverse_list(list, previous=nil)
# set current_head to node2
current_head = list.next_node
# Change node3.next_node node2-->nil
list.next_node = previous
if current_head
# reverse_list(node2, node3)
reverse_list(current_head, list)
else
list
end
end
第二次进入reverse_list方法
reverse_list(node2, node3)
def reverse_list(list, previous=nil)
# set current_head to node1
current_head = list.next_node
# Change node2.next_node node1-->node3
list.next_node = previous
if current_head
# reverse_list(node1, node2)
reverse_list(current_head, list)
else
list
end
end
最后进入reverse_list方法
reverse_list(node1, node2)
def reverse_list(list, previous=nil)
# set current_head to nil
current_head = list.next_node
# Change node1.next_node nil-->node2
list.next_node = previous
if current_head
reverse_list(current_head, list)
else
# The end, return node1
list
end
end
顺便说一下,链表不是ruby语言中的常见做法(以及带有垃圾收集器的所有语言),通常有一个类(例如Array),它具有您可能需要的所有功能和灵活性
答案 2 :(得分:3)
如果有人希望在没有递归的情况下执行此操作,这是一个简单的解决方案
class Node
attr_accessor :value, :next
def initialize(value, next_node)
@value = value
@next = next_node
end
end
class LinkedList
attr_accessor :head, :tail
def add(value)
if(@head.nil?)
@head = Node.new(value, nil)
@tail = @head
else
@tail.next = Node.new(value, nil)
@tail = @tail.next
end
end
def reverse(list)
return nil if list.nil?
prev = nil
curr = list.head
while(curr != nil)
temp = curr.next
curr.next = prev
prev = curr
curr = temp
end
list.head = prev
list
end
def display(list)
return nil if list.nil?
curr = list.head
arr = []
while(curr != nil)
arr.push(curr.value)
curr = curr.next
end
p arr
end
end
list = LinkedList.new()
list.add(1)
list.add(2)
list.add(3)
list.display(list) #list before reversing [1,2,3]
list.display(list.reverse(list)) #list after reversing [3,2,1]