我有以下链接列表实现:
class LinkedList
def initialize
@head = nil
end
def return_head
previous_head = @head
previous_head.next = nil # I want to return a clean node, without nexts
@head = @head.next
return previous_head
end
def add_element(value)
if @head.nil?
@head = Node.new(value)
else
new_node = Node.new(value)
@head.next = new_node
end
end
end
class Node
attr_accessor :data, :next
def initialize(data)
@data = data
end
end
我的问题在于return_head方法。当我做previous_head.next = nil
时,因为我想返回一个节点,头部本身,没有下一个。由于我将下一个设置为nil,然后当我执行@head = @head.next
时,@head
为nil
我怎么解决这个问题?
答案 0 :(得分:0)
def return_head
previous_head = @head
next_head = @head.next
@head.next = nil # I want to return a clean node, without nexts
@head = next_head
return previous_head
end
答案 1 :(得分:0)
您的问题是,您将@head
和previous_head
视为不同的对象,但它们不是。
致电时
previous_head.next = nil # I want to return a clean node, without nexts
next
的{{1}}属性(因此previous_head
)设置为@head
,因此当您尝试再次从nil
访问它时已经@head
。
要解决此问题,您需要颠倒操作顺序,首先设置新的nil
,然后从@head
中删除next
节点:
previous_head
另外,您可能还想查看@ Cary的答案,因为您的 def return_head
previous_head = @head
@head = @head.next
previous_head.next = nil # I want to return a clean node, without nexts
return previous_head
end
方法实际上并没有添加元素,而是替换了第二个元素(您可以“#l; ll有一个零,一个或两个元素的列表 - 不再......)
答案 2 :(得分:0)
add_elements
有一个错误:@head
在添加第一个元素后永远不会更改,只会更改@head.next
。
即使修复了add_elements
,但如果没有干预return_head
,则无法执行add_element
两次。如果连续两次调用return
head,你也可以实现一个简单的堆栈。
要连续执行return_head
两次或更多次,您需要保存列表的第一个节点并使用node.next
逐步浏览列表,直到找到倒数第二个节点。我已在单链接列表下完成此操作。
删除节点时,我选择返回node.data
,而不是node
,因为后者已从列表中删除,因此您只需提取data
即可
您的另一个选择是实现双链表,我在下面也做了。
<强>代码强>
class SingleLinkedList
attr_reader :head
def initialize
@head = nil
@tail = nil
end
def delete_and_return_head
data = @head.data
delete_head
data
end
def delete_head
return if @head.nil?
if @start == @head
@start = nil
@head = nil
else
@head = find_prev
@head.next = nil
end
end
def add_element(value)
new_node = Node.new(value)
if @head.nil?
@start = new_node
else
@head.next = new_node
end
@head = new_node
end
private
def find_prev
node = @start
node = node.next while node.next.next
node
end
end
class Node
attr_accessor :data, :next
def initialize(data)
@data = data
end
end
示例强>
创建链接列表
l = SingleLinkedList.new #=> #<SingleLinkedList:0x0000010200be70 @head=nil, @tail=nil>
添加元素
l.add_element(:dog) #=> #<Node:0x0000010184cbf8 @data=:dog>
l.head #=> #<Node:0x0000010184cbf8 @data=:dog>
l.head.data #=> :dog
l.head.next #=> nil
dog = l.head #=> #<Node:0x0000010184cbf8 @data=:dog>
l.add_element(:cat) #=> #<Node:0x00000102207da0 @data=:cat>
l.head.data #=> :cat
dog.next.data #=> :cat
cat = l.head #=> #<Node:0x00000102207da0 @data=:cat>
l.add_element(:pig) #=> #<Node:0x000001021e4dc8 @data=:pig>
l.head.data #=> :pig
cat.next.data #=> :pig
删除并返回元素
l.delete_and_return_head #=> :pig
l.head.data #=> :cat
l.head.next #=> nil
l.delete_and_return_head #=> :cat
l.head.data #=> :dog
l.head.next #=> nil
<强>代码强>
class DoubleLinkedList
attr_reader :head
def initialize
@head = nil
end
def delete_and_return_head
data = @head.data
delete_head
data
end
def delete_head
return nil if @head.nil?
if @head.prev.nil?
@head = nil
else
@head.prev.next = nil
@head = @head.prev
end
end
def add_element(value)
new_node = Node.new(value)
unless @head.nil?
new_node.prev = @head
@head.next = new_node
end
@head = new_node
end
end
class Node
attr_accessor :data, :next, :prev
def initialize(data)
@data = data
end
end
示例强>
创建链接列表
l = DoubleLinkedList.new #=> #<DoubleLinkedList:0x00000101048a60 @head=nil>
添加元素
l.add_element(:dog) #=> #<Node:0x00000101039a60 @data=:dog>
l.head #=> #<Node:0x00000101039a60 @data=:dog>
l.head.data #=> :dog
l.head.prev #=> nil
l.head.next #=> nil
dog = l.head #=> #<Node:0x00000101039a60 @data=:dog>
l.add_element(:cat) #=> #<Node:0x00000101874450 @data=:cat,
# @prev=#<Node:0x00000101039a60 @data=:dog>>
l.head.data #=> :cat
l.head.prev.data #=> :dog
dog.next.data #=> :cat
cat = l.head #=> #<Node:0x00000101874450 @data=:cat,
# @prev=#<Node:0x00000101039a60 @data=:dog>>
l.add_element(:pig) #=> #<Node:0x00000101110fb0 @data=:pig,
# @prev=#<Node:0x00000101874450 @data=:cat,
# @next=#<Node:0x00000101110fb0 ...>,
# @prev=#<Node:0x00000101039a60 @data=:dog>>>
l.head.data #=> :pig
l.head.prev.data #=> :cat
cat.next.data #=> :pig
删除并返回元素
l.delete_and_return_head #=> :pig
l.head.data #=> :cat
l.head.next #=> nil
l.head.prev.data #=> :dog
dog.next.data #=> :cat
l.delete_and_return_head #=> :cat
l.head.data #=> :dog
l.head.next #=> nil
l.head.prev #=> nil