尽管定义了main:Object(NoMethodError)的Ruby未定义方法`merge_lists'

时间:2018-10-25 20:41:12

标签: ruby merge linked-list undefined nomethoderror

我得到的错误没有道理。我尝试重新定位 #merge_lists 方法,该方法不必要。我还查看了其他SO问题,但对我的情况没有帮助。在链接列表对象上执行 methods.sort 会显示 #merge_lists 方法。有人可以告诉我我哪里出问题了吗?任何帮助将不胜感激。

错误消息

Traceback (most recent call last): node.rb:269:in':未定义的方法merge_lists' for main:Object (NoMethodError)

代码

class Node
  attr_accessor :next
  attr_accessor :data

  def initialize(data)
    @data = data
    @next = nil
  end
end

class LinkedList
  attr_accessor :head 

  def initialize
    self.head = nil
  end

  # Inserts a new node at the beginning of Linked List.

  def push(new_data)
    new_node = Node.new(new_data)
    new_node.next = self.head
    self.head = new_node
  end



  # Inserts a new node after the given prev_node.

  def insert_after_node(prev_node, new_data)
     # 1. check if the given prev_node exists

    return "Previous node must be in the LinkedList" if prev_node.nil?


    #  2. Create new node &
    #  3. Put in the data

    new_node = Node.new(new_data)

    # 4. Make next of new Node as next of prev_node

    new_node.next = prev_node.next

    # 5. make next of prev_node as new_node

    prev_node.next = new_node
  end
  #

  # # Appends a new node at the end.  This method is

  def append(new_data)
    # 1. Create a new node
    # 2. Pass in the data
    # 3. Set next as Nil

    new_node = Node.new(new_data)

    # 4. If the Linked List is empty, then make the
    #    new node head

    if self.head.nil?
      self.head = new_node
    else

      # 5. Else traverse till the last node
      last = self.head

      while last.next
        last = last.next

        last.next = new_node

      end
    end

  end


  # Function to merge two sorted linked list.
  def merge_lists(head1, head2)
    # create temp node Nil
    temp = nil

    # if list 1 or list 2 is empty return it

      return head1 if head1.nil?
      return head2 if head2.nil?

      # if list1's data is smaller or equal to list2's data

      if head1.data <= head2.data

        # assign temp to list1's data
        temp = head1

        # Recheck if list1's data is smaller or equal to list2's data
        # and call merge_lists method

        temp.next = merge_lists(head1.next, head2)
      else

        # If List2's data is greater than or equal List1's
        # data assign temp to head2

        temp = head2

        # Recheck if list1's data is smaller or equal to list2's data
        # and call merge_lists method

        temp.next = merge_lists(head1, head2.next)
      end

      # return temp list.
      return temp
  end

  # This function counts number of nodes in Linked List

  def count
    temp = self.head # Initialize temp
    count = 0 #Initialize count

    while temp
      count += 1
      temp = temp.next
    end
    count
  end


  def print_list
    current = self.head

    puts current.data

    until current.next == nil
      current = current.next
      puts current.data
    end

  end

end

llist = LinkedList.new
llist.append(6)
llist.push(1);
llist.push(7);
llist.push(13);
llist.insert_after_node(llist.head.next, 8)
"#{llist.print_list}"
puts "Number of Nodes in LinkedList: #{llist.count}"

llist2 = LinkedList.new
llist2.append(21)
llist2.push(40);
llist2.push(75);
llist2.push(32);
llist2.insert_after_node(llist2.head.next, 80)


"#{llist2.print_list}"
puts "Number of Nodes in LinkedList2: #{llist2.count}"

"Merged Lists: #{merge_lists(llist.head, llist2.head).print_list}"

**Full Backtrace**
    ===================== initialize
[]
===================== append
[[:new_data, 6]]
===================== initialize
[[:data, 6]]
===================== push
[[:new_data, 1]]
===================== initialize
[[:data, 1]]
===================== push
[[:new_data, 7]]
===================== initialize
[[:data, 7]]
===================== push
[[:new_data, 13]]
===================== initialize
[[:data, 13]]
===================== insert_after_node
[[:prev_node, #<Node:0x00007fd2d21f09d0 @data=7, @next=#<Node:0x00007fd2d21f23c0 @data=1, @next=#<Node:0x00007fd2d21f3ef0 @data=6, @next=nil>>>], [:new_data, 8]]
===================== initialize
[[:data, 8]]
===================== print_list
[]
13
7
8
1
6
===================== count
[]
Number of Nodes in LinkedList: 5
===================== initialize
[]
===================== append
[[:new_data, 21]]
===================== initialize
[[:data, 21]]
===================== push
[[:new_data, 40]]
===================== initialize
[[:data, 40]]
===================== push
[[:new_data, 75]]
===================== initialize
[[:data, 75]]
===================== push
[[:new_data, 32]]
===================== initialize
[[:data, 32]]
===================== insert_after_node
[[:prev_node, #<Node:0x00007fd2d2207bd0 @data=75, @next=#<Node:0x00007fd2d21f6830 @data=40, @next=#<Node:0x00007fd2d29493d0 @data=21, @next=nil>>>], [:new_data, 80]]
===================== initialize
[[:data, 80]]
===================== print_list
[]
32
75
80
40
21
===================== count
[]
Number of Nodes in LinkedList2: 5
Traceback (most recent call last):
node.rb:279:in `<main>': undefined method `merge_lists' for main:Object (NoMethodError)

1 个答案:

答案 0 :(得分:0)

这是因为您正在调用merge_lists而没有任何对象(但main:Object),因此Ruby无法定义该方法。

使merge_listsdef LinkedList.merge_lists(head1, head2)这样的class methodLinkedList.merge_lists(llist.head, llist2.head)一样使用

请记住,merge_lists返回Node而不是LinkedList,因此会引发错误:

undefined method `print_list' for #<Node:0x000055bed3397a28>