快速排序算法--Ruby实现

Quicksort Algorithm--Ruby Implementation

我一直在努力调试我的快速排序实现,并且可以使用一双新的眼睛。我正在学习 Robert Sedgewick 的 Coursera 算法课程,我完全不知道我这样做的方式有什么问题(看起来与他的 java 实现几乎相同)。有任何想法吗?我知道我的分区方法是有效的,因为我已经对其进行了广泛的压力测试(即,如果我提交低为 0 和高为 2,则数组将在这些索引之间正确分区)。

另外,我使用快速排序作为就地排序,所以这就是我不创建辅助数组的原因。

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

partition 应该 return j。见对应的java code.

#2

您已经在 quicksort 中打乱了数组,无需在 partition 中一次又一次地打乱它!

此外,请注意,您的 shuffle 方法会随机播放整个数组,独立于 jlowhigh

在每次迭代中仅分别改组左右子数组是可行的,即使它是不需要的。

#3

quicksort 应该 return 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]