2014-10-07 3 views
-2

Мне нужно сделать вид пузыря в рубине для проекта, и у меня проблемы. Я перевел псевдокод на wikipedia на ruby, и он работает не так, как ожидалось. Я не совсем уверен, что случилось.Проблема с Ruby Bubble Сортировка

swapped = false 

def bubble_sort(list,swapped) 
    length = list.length 
    i = 1 
    until !swapped do 
     swapped = false 
     list.each do |i| 
      if list[i-1] > list[i] 
       list[i-1], list[i] = list[i], list[i-1] 
       swapped = true 
      end 
     end 
    end 
    return list 
end 

puts bubble_sort([1,3,7,4,6,9,10,5,8,2], swapped) 
+1

Каким образом это не работает? –

+0

Он печатает исходный массив, который прошел. – jdublu10

+2

Проводили ли вы какую-либо отладку вообще? Я не помню, как должен работать пузырь, но сделанная вами ошибка стала бы очевидной даже при минимальных усилиях по отладке. Я дам вам подсказку, я бы расследовал блок list.each. Это и вам не хватает рекурсивной части алгоритма. –

ответ

1

Ваша главная проблема здесь:

until !swapped do 

так swapped ложно, цикл не выполняется ни разу.

Кроме того:

list.each do |i| 
    if list[i-1] > list[i] 
     list[i-1], list[i] = list[i], list[i-1] 
     swapped = true 
    end 
end 

i не является индексом, но значение, следовательно, list[i-1] для третьего элемента будет оценивать с list[6] (третий элемент 7). Вместо этого вы должны использовать индекс:

list.each_index do |i| 
    if list[i-1] > list[i] 
     list[i-1], list[i] = list[i], list[i-1] 
     swapped = true 
    end 
end 

Другая проблема заключается в том, что list[-1] является допустимым синтаксисом и возвращает последний элемент массива. Вам нужно пропустить этот элемент. Ваша логика swapped здесь неверна, вы устанавливаете ее в true, как только вы меняете первые элементы, что изменило условие на false и разрывает цикл, вы должны установить его наоборот.

def bubble_sort(list) 
    swapped = true 
    while swapped do 
    swapped = false 
    list.each_index do |i| 
     next if i == 0 
     if list[i-1] > list[i] 
     list[i-1], list[i] = list[i], list[i-1] 
     swapped = true 
     end 
    end 
    end 
    list 
end 

Немногие примечания, вам не нужен оператор return, метод ruby ​​возвращает значение последней выполненной строки. Передача swapped в качестве параметра полностью устарела.

Смежные вопросы