泡泡排序算法中的Ruby无限循环

时间:2016-05-05 13:39:54

标签: ruby algorithm loops infinite-loop bubble-sort

我用Ruby构建了基本的冒泡排序算法,没有任何问题。代码如下:

def bubble_sort(arr)
 swapped=true
 while swapped
    swapped=false
    for j in 0..arr.length-2 do
      if arr[j]>arr[j+1]
        arr[j], arr[j+1] = arr[j+1], arr[j]
        swapped=true
      end
    end
 end
arr
end

现在,我正在尝试实现相同的方法,但具有接受代码块的功能。代码块部分工作正常,但是当没有提供代码块时,该方法应该像上面一样工作,虽然它在逻辑上看起来与我相同,但由于某种原因,它会进入无限循环:

在“除非”行上,如有必要,它将检查条件和交换位置,并跳过产量部分。我试过rdebugger一步一步的调试,但找不到原因。

def bubble_sort_by(arr)
  swapped = true
  while swapped
    swapped=false
    for i in 0..arr.length-2 do
      unless block_given?
        arr[i], arr[i+1] = arr[i+1], arr[i] if arr[i] < arr[i+1]
        swapped=true
      end #unless
    if block_given?
      if yield(arr[i], arr[i+1])>0
        arr[i], arr[i+1] = arr[i+1], arr[i]
        swapped=true
      end #if yield
    end #if block_given?
    end #for
  end #while
puts arr
return arr
end

2 个答案:

答案 0 :(得分:1)

快速回答:

arr[i], arr[i+1] = arr[i+1], arr[i] if arr[i] < arr[i+1]
swapped=true

应替换为:

if arr[i] < arr[i+1]
  arr[i], arr[i+1] = arr[i+1], arr[i]
  swapped=true
end

即使没有交换元素,您仍然总是swapped设置为true。所以你陷入无限循环。

现在进行一些代码清理......首先,而不是写作:

if(foo)
  # ...
end
unless(foo)
  # ...
end

让它成为if / else声明:

def bubble_sort_by(arr) 
  swapped = true 

  while swapped 
    swapped=false 
    for i in 0..arr.length-2 do 
      if block_given? 
        if yield(arr[i], arr[i+1])>0 
          arr[i], arr[i+1] = arr[i+1], arr[i] 
          swapped=true 
        end 
      else 
        if arr[i] < arr[i+1] 
          arr[i], arr[i+1] = arr[i+1], arr[i] 
          swapped=true 
        end 
      end 
    end #for 
  end #while 

  return arr 
end

你可以进一步重新考虑它,以删除@Aetherus建议的while循环,但我认为你很高兴看到实际的错误修复。

答案 1 :(得分:0)

您的代码有太多block_given?,我不明白为什么需要布尔变量swapped

这是我的冒泡排序版本(因为它对阵列进行了排序,我给它起了一个名字)。

def bubble_sort!(arr, &compare)
  # Provide a default comparison algorithm
  compare ||= proc {|a, b| a <=> b}

  (1...arr.length).each do |i|
    (0...i).each do |j|
      arr[i], arr[j] = arr[j], arr[i] if compare.call(arr[i], arr[j]) < 0
    end
  end

  arr
end