Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby Heapsort:`sink';:未定义的方法`>';零级:零级_Ruby_Algorithm_Heapsort - Fatal编程技术网

Ruby Heapsort:`sink';:未定义的方法`>';零级:零级

Ruby Heapsort:`sink';:未定义的方法`>';零级:零级,ruby,algorithm,heapsort,Ruby,Algorithm,Heapsort,我目前正在写这本书。我试图实现堆排序,但遇到了一个错误 “sink”:nil:NilClass的未定义方法>” 发生此错误的原因是,当数组被传递到sort方法时,它在0索引处有11个元素。当它用1交换索引n(数组中的元素数)时,将nil与字符串进行比较。意思是n是11,但是没有11索引,因为数组索引从0开始 以下是本书中堆排序方法的Java实现: public static void sort(Comparable[] a) { int N = a.length; fo

我目前正在写这本书。我试图实现堆排序,但遇到了一个错误

“sink”:nil:NilClass的未定义方法>”

发生此错误的原因是,当数组被传递到
sort
方法时,它在0索引处有11个元素。当它用1交换索引
n
(数组中的元素数)时,将
nil
与字符串进行比较。意思是
n
是11,但是没有11索引,因为数组索引从0开始

以下是本书中堆排序方法的Java实现:

 public static void sort(Comparable[] a)
  {
     int N = a.length;
     for (int k = N/2; k >= 1; k--)
        sink(a, k, N);
     while (N > 1)
     {
        exch(a, 1, N--);
        sink(a, 1, N);
     }
}
 
下面是Ruby中的实现:

  def sort(a)
    n = a.length
    k = n/2
    while k >= 1
      sink(a, k, n)
      k -= 1
    end
    
    while n > 1
      swap(a, 1, n)
      n -= 1
      sink(a, 1, n)
    end
    a
  end
现在,在这本书中,数组忽略了位置
a[0]
并从
a[1]
开始,但我有点不清楚Java实现中的
sort
方法是如何实现的。我也有点奇怪,该方法需要传递一个从索引
1
开始的数组。因此我的理解是Java实现中的
sort
方法将设置数组

请注意,在示例中,数组中的第一个元素是如何从索引1
a[1]
开始的。这是在
排序方法中完成的吗?意思是重新排列数组以从索引1开始

Ruby中
sort
的Ruby实现是否正确?还是有错误

堆排序的完整实现

class Heap
  # Trickledown
  def sink(a, k, n)
    while 2 * k <= n
      j = 2 * k # child

      if !a[j + 1].nil? # check if there is a right child
        j += 1 if j > 1 && less(a, j, j + 1) # if left child less than right child
      end

      break if !less(a, k, j) # If parent greater than child break

      swap(a, k, j)
      k = j
    end
  end

  def sort(a)
    n = a.length
    k = n / 2

    while k >= 1
      sink(a, k, n)
      k -= 1
    end

    while n > 1
      swap(a, 1, n)
      n -= 1
      sink(a, 1, n)
    end
    a
  end

  def less(pq, i, j)
    pq[i - 1] < pq[j - 1]
  end

  def swap(a, i, j)
    temp = a[i - 1]
    a[i - 1] = a[j - 1]
    a[j - 1] = temp
  end
end

input = ["S", "O", "R", "T", "E", "X", "A", "M", "P", "L", "E"]

heap = Heap.new
p heap.sort(input)
但正确的答案是

 ["A", "E", "E", "L", "M", "O", "P", "R", "S", "T", "X"] 

错误来自以下行:

if !a[j + 1].nil? # check if there is a right child
此行检查是否存在右节点。堆排序实现中的问题是,我们在每次迭代中将
n
减少一个

 while n > 1
    swap(a, 1, n)
    n -= 1
    sink(a, 1, n)
 end
因此,我们没有跟踪数组中存储在索引
n
上的元素。虽然数组中存储有值,但我们仅将
a[0]
a[n]
视为堆。

因此,我不应该检查
a[j+1]
是否为零,而应该检查
j+1
是否小于或等于
n

  def sink(a, k, n)
    while 2 * k <= n
      j = 2 * k # child

      if j + 1 <= n # check if there is a right child
        j += 1 if j > 1 && less(a, j, j + 1) # if left child less than right child
      end

      break if !less(a, k, j) # If parent greater than child break
      swap(a, k, j)
      k = j
    end
  end
def接收器(a、k、n)

而2*k错误消息指向
sink
方法。如果a[k]>a[j]
,则可以调用
的唯一行是
中断。我猜在一些
swap
call(s)之后,初始数组被
nil
s损坏,因为[a.size]是
nil
,并且您的
n
可以达到
s.size
正确,这就是我在帖子中描述的。但是在Java实现中是如何做到这一点的呢?请注意数组是如何从索引1开始的。您将获得数据的中间快照。跟踪执行情况并验证快照是否相同。
  def sink(a, k, n)
    while 2 * k <= n
      j = 2 * k # child

      if j + 1 <= n # check if there is a right child
        j += 1 if j > 1 && less(a, j, j + 1) # if left child less than right child
      end

      break if !less(a, k, j) # If parent greater than child break
      swap(a, k, j)
      k = j
    end
  end