修改Ruby中的调用对象



我正在学习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

相关内容

  • 没有找到相关文章

最新更新