Quicksort算法 - Ruby实现

时间:2016-12-26 17:42:37

标签: ruby algorithm quicksort

一直在试图调试我的quicksort实现并且可以使用一组新的眼睛。我跟随Robert Sedgewick的Coursera算法课程,我完全不知道我这样做的方式有什么不对(看起来与他的java实现几乎相同)。有任何想法吗?我知道我的分区方法有效,因为我已经对它进行了大量的压力测试(即如果我将低电平提交为0而高电平为2,则数组将在这些索引之间正确分区)。

另外,我使用quicksort作为就地排序,这就是我没有创建辅助数组的原因。

def shuffle(arr)
  arr.each_index do |i|
    r = rand(0..i)
    arr[i], arr[r] = arr[r], arr[i]
  end
  arr
end

def partition!(arr,low, high)
  #debugger
  arr = shuffle(arr)
  i = low + 1 
  j = high
  while true 
    until arr[i] >= arr[low]
      break if i >= high
      i+=1
    end

    until arr[j] <= arr[low]
      j-=1
    end

    if i>=j 
      #done 
      arr[j], arr[low] = arr[low], arr[j]
      break 
    else 
      #swap and continue
      arr[i], arr[j] = arr[j], arr[i]
    end
  end 
end


def quicksort(arr, low = 0, high=arr.length-1)
  arr = shuffle(arr)
  quicksort!(arr, low, high)
end

def quicksort!(arr, low, high)
   #p "Quicksorting on low index #{low} and high index #{high}"
   return arr if (high <= low)
   j = partition!(arr, low, high)
   quicksort!(arr, low, j-1)
   quicksort!(arr, j+1, high)
end

1 个答案:

答案 0 :(得分:0)

你快到了。

问题

#1

partition应该返回j。请参阅相应的java code

#2

您已经在quicksort中对数组进行了随机播放,无需在partition中反复对其进行随机播放!

另请注意,您的shuffle方法会独立于jlowhigh对整个数组进行随机播放。

在每次迭代时仅分别对左右子阵列进行混洗会起作用,即使它不需要。

#3

quicksort应该返回arr

完整代码

def shuffle(arr)
  arr.each_index do |i|
    r = rand(0..i)
    arr[i], arr[r] = arr[r], arr[i]
  end
  arr
end

def partition!(arr,low, high)
  i = low + 1 
  j = high
  while true 
    until arr[i] >= arr[low]
      break if i >= high
      i+=1
    end

    until arr[j] <= arr[low]
      j-=1
    end

    if i>=j 
      #done 
      arr[j], arr[low] = arr[low], arr[j]
      break 
    else 
      #swap and continue
      arr[i], arr[j] = arr[j], arr[i]
    end
  end 
  j
end


def quicksort(arr, low = 0, high=arr.length-1)
  arr = shuffle(arr)
  quicksort!(arr, low, high)
  arr
end

def quicksort!(arr, low, high)
   return arr if (high <= low)
   j = partition!(arr, low, high)
   quicksort!(arr, low, j-1)
   quicksort!(arr, j+1, high)
end

arr = [3,2,1,4,5]
p quicksort(arr)
# => [1, 2, 3, 4, 5]