Ruby中的插入排序

时间:2012-10-29 04:36:06

标签: ruby

以下是C ++中插入排序的算法(来自教程):

void insertionSort(int arr[], int length) {
      int i, j, tmp;
      for (i = 1; i < length; i++) {
            j = i;
            while (j > 0 && arr[j - 1] > arr[j]) {
                  tmp = arr[j];
                  arr[j] = arr[j - 1];
                  arr[j - 1] = tmp;
                  j--;
            }
      }
}

这就是我在Ruby中所做的事情

a = [12, 1, 18, -3, -2, 66, 31]
puts a

def insertion_sort(source)
    source.to_enum.with_index(1).each do |item, i|
        j = i
        while((j>0) && (source[j-1] > source[j]))
            source[j], source[j-1] = source[j-1], source[j]
            j -= 1  
        end
    end
end

insertion_sort(a)
puts a

它会引发comparison of Fixnum with nil failed (ArgumentError)的错误。可能是因为溢出。

我做错了什么?

2 个答案:

答案 0 :(得分:2)

C++版本中,您有(i = 1; i < length; i++)。这意味着,它不会运行i = length的最后一轮。这将超出阵列。

ruby中,因为您将索引的偏移量设置为1,即最后一轮,您将拥有i = length。因此source[length]超出source,因此返回nil

1 > nil  # source[j-1] > source[j] when j = length
# ArgumentError: comparison of Fixnum with nil failed

答案 1 :(得分:1)

虽然@oldergod已经回答了你的问题,但我只想补充一些问题。

此处的代码示例取自algorithm gem

def insertion_sort(container)
  return container if container.size < 2
  (1..container.size-1).each do |i|
    value = container[i]
    j = i-1
    while j >= 0 and container[j] > value do
      container[j+1] = container[j]
      j = j-1
    end
    container[j+1] = value
  end
  container
end

在这里,您将容器的第二个索引1迭代到最后一个索引container.size - 1