在使用 Ruby 解决插入排序时,整数与 nil 的比较失败(ArgumentError)

Comparison of Integer with nil failed (ArgumentError) while solving Insertion Sort with Ruby

下面是更新后的代码:

def insertion_sort(list)
  num = list.length
  for i in (0..(num-2))
    if list[i] > list[i+1] && i == 0
      list[i], list[i+1] = list[i+1], list[i]
      i+=1
    elsif list[i] == list[i+1]
      i+=1
    elsif list[i] > list[i+1] && i > 0
      len = (list[0..(i+1)].length)
      list2 = list[0..(i+1)]
      list = list - list2
      count = 0
      while count <= len+1
        if list2[len-1] < list2[len-2]
           list2[len-2],list2[len-1]= list2[len-1],list2[len-2] 
        elsif  list2[len-1] == list2[len-2]
          count+=1
          len-=len
        else
         count+=1
         len-=1 
        end
      end
       list = list2 + list  
    end
  end
   list
end

p insertion_sort([2,1,4,8,7,3,100,99,8])
p insertion_sort([2,1,4,8,8,7,3,100,99])
p insertion_sort([3790,780,780,1,55])

总结:

  1. 如果两个相同的整数彼此相邻,则代码有效:[2,1,4,8,8,7,3,100,99] 并且数组大小 > 5。
  2. 如果两个相同的整数在随机位置:[2,1,4,8,7,3,100,99,8]。会出现以下错误 aaa.rb:4:in `>': Integer 与 nil 的比较失败 (ArgumentError)

第 4 行代码为:if list[i] > list[i+1] && i == 0

解决1.我把while循环改成了"while count <= len+1", 因此,当数组大小小于 5 时,代码将起作用。但当相同的整数位于随机位置时则不然。

有人知道怎么解决吗? 提前致谢!

感谢评论中的澄清。我现在看到问题了。

在这里交换算法

elsif list[i] > list[i+1] && i > 0
  len = (list[0..(i+1)].length)
  list2 = list[0..(i+1)]
  list = list - list2
  count = 0
  while count <= len+1
    ...

您正试图将数组一分为二。你得到 list2 这是数组的前半部分,然后尝试通过 减去 list2 得到后半部分来自 list.

这里使用 subtract 的问题是,如果您有重复项,它将删除它们并使您的列表太短。

在示例 [3790,1,780,55,23,50,1111,60,50] 中,您应该在第一个数组中有一个 50,在后半部分中有一个 50

但是使用 subtract 会删除其中一个 50

当您将两个临时列表加回一起时,您现在少了一个元素(缺少 50),当您到达数组末尾并尝试访问时,您会遇到越界错误这第 9 个元素不再存在。

不要在这里使用减法,只需使用与 list2.

相同的方法
list2 = list[0..(i+1)] # All elements in list from position 0 to i+1
list = list[(i+2)..-1] # All elements in list from position i+2 to end of list

现在 listlist2 只是原始列表拆分,当您将它们重新组合在一起时,它们的长度应该相同

def insertion_sort(list)
  num = list.length
  for i in (0..(num-2))
    if list[i] > list[i+1] && i == 0
      list[i], list[i+1] = list[i+1], list[i]
      i+=1
    elsif list[i] == list[i+1]
      i+=1
    elsif list[i] > list[i+1] && i > 0
      len = (list[0..(i+1)].length)
      list2 = list[0..(i+1)]
      list = list[(i+2)..-1]
      count = 0
      while count <= len+1
        if list2[len-1] < list2[len-2]
           list2[len-2],list2[len-1]= list2[len-1],list2[len-2] 
        elsif  list2[len-1] == list2[len-2]
          count+=1
          len-=len
        else
         count+=1
         len-=1 
        end
      end
       list = list2 + list  
    end
  end
   list
end

p insertion_sort([2,1,4,8,7,3,100,99,8])
p insertion_sort([2,1,4,8,8,7,3,100,99])
p insertion_sort([3790,780,780,1,55])