2013-03-17 52 views
0

我正在学习Ruby,并且正在做一个链接列表类。我正在编写双向链表的删除方法。我的问题是,如果我通过它的头节点表示列表,我该如何删除头部?看起来Ruby不会让你指定自变量,所以我不能将调用者的引用改为下一个节点。一种解决方案是我可以从下一个节点和交​​换引用中复制密钥,但是通常情况下,Ruby中是否有方法来更改调用者的引用?在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 

回答

0

你不能改变被指向的哪个对象,被调用者(即修改self),但你可以操纵的对象在任何你想要的,因为你已经想到过。简短的答案是它不能完成。你可以想出其他方法来模拟它,但我认为你已经走上了正轨。

0

您需要以不同方式概念化链接列表。 LinkedListNode是LinkedList的一个组件,而不是LinkedList本身。像append,delete和print这样的操作应该放在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