我正在学习Ruby的过程中,作为实践,我正在制作一个链表类。我正在为一个双重链表编写删除方法。我的问题是,如果我用它的头节点来表示列表,我怎么删除它的头呢?似乎Ruby不允许你给self变量赋值,所以我不能把调用者的引用改为下一个节点。一种解决方案是,我可以从下一个节点复制键并交换引用,但一般来说,在Ruby中有办法更改调用者的引用吗?
class LinkedListNode
attr_accessor :next, :previous, :key
def initialize(key=nil, next_node=nil, previous=nil)
@next = next_node
@previous = previous
@key = key
end
def append(key=nil)
newnode = LinkedListNode.new(key)
seeker = self
while seeker.next != nil
seeker = seeker.next
end
newnode.previous = seeker
seeker.next = newnode
end
def delete(key=nil)
seeker = self
while seeker.key != key
return if seeker.next == nil
seeker = seeker.next
end
if seeker.previous != nil
if seeker.next != nil
seeker.previous.next = seeker.next
seeker.next.previous = seeker.previous
else
seeker.previous.next = nil
end
else
return self = self.next
end
return seeker = nil
end
def print
seeker = self
string = ""
while 1
if seeker.next == nil
string += seeker.key.to_s
break
else
string += seeker.key.to_s + " -> "
end
seeker = seeker.next
end
puts string
end
end
if __FILE__ == $0
ll = LinkedListNode.new(1)
ll.append(2)
ll.append(3)
ll.append(4)
ll.append(5)
ll.print
ll.delete(5)
ll.print
ll.delete(1)
ll.print
end
您不能更改调用者所指向的对象(即修改self
),但您可以以任何您想要的方式操作对象,正如您已经考虑过的那样。简短的回答是,这是不可能做到的。你可以想出其他的方法来模拟它,但我认为你已经在正确的轨道上了。
您需要以不同的方式概念化链表。LinkedListNode是LinkedList的一个组件,而不是LinkedList本身。诸如追加、删除和打印等操作应该在LinkedList类中进行,而不是在LinkedListNode类中。试着以
开头class LinkedList
# This one-liner defines a LinkedList::Node with associated constructor
# and accessors for the three tags provided. Any tags omitted during
# construction will be initialized to nil.
Node = Struct.new(:key, :previous, :next)
attr_reader :head, :tail
def initialize
# start with no Nodes in the list
@head = @tail = nil
end
def append(key)
# Make the LinkedList tail a new node that stores the key,
# points to the prior tail as its previous reference, and
# has no next.
@tail = Node.new(key, @tail)
if @tail.previous # the prior tail was not nil
@tail.previous.next = @tail # make the prior tail point to the new one
else # if there wasn't any tail before the list was empty
@head = @tail # so the new tail Node is also the head
end
end
# ...
end