【发布时间】:2015-02-06 09:37:12
【问题描述】:
我知道有人问过很多类似的问题。我已经阅读了它们,但仍然不明白为什么我的代码会这样做。它仅用于培训,我已经实现了一个简单的 LinkedList(单链接),我想实现两个这样的排序列表的合并。这是代码
#!/usr/bin/ruby
#
module LinkedList
class Node
attr_accessor :next,:data
def to_s
s = @data.to_s + " -> "
s += @next.to_s if @next
s
end
end
end
def append tail, node
tail.next = node
tail = node
node = node.next
end
def merge_lists2 list1, list2
tail = LinkedList::Node.new
while(list1 && list2)
list1.data <= list2.data ? list1 = append(tail,list1) : list2 = append(tail,list2)
puts list1
puts list2
puts tail
puts "#######################################################"
STDIN.gets
end
if list1
tail.next = list1
elsif list2
tail.next = list2
end
tail.next
end
def generateList times = 3,factor = 1
list = LinkedList::Node.new
list.data = 0
curr = list
(1..times).each do |i|
curr.next = LinkedList::Node.new
curr = curr.next
curr.data = i*factor
end
list
end
def main
l1 = generateList 4,2
l2 = generateList 5,1.5
puts l1
puts l2
l3 = merge_lists2 l1,l2
puts l3
end
以下代码是我的“旧”版本:
def append tail, node
tail.next = node
tail = node
node = node.next
end
def merge_lists2 list1, list2
tail = LinkedList::Node.new
while(list1 && list2)
list1.data <= list2.data ? append(tail,list1) : append(tail,list2)
在旧版本中,它在无限循环中运行,因为 list1 和 list2 从未更新,因此 while 循环一直在进行。它们从未更新,因为 list1 和 list2 变量在 append 函数中被分配给不同的对象,因此当从函数返回时,list1 和 list2 会“收回”它们的原始引用。 但是“尾巴”参考已更新!运行代码可以看到,tail 始终是新合并列表的“尾”,而不是新列表的“头”。我不明白为什么因为 tail 还引用了 append 的新对象,所以当从函数返回时,“tail”应该仍然是“head”(哈哈,这太疯狂了)
谢谢...
【问题讨论】:
标签: ruby pass-by-reference pass-by-value