【问题标题】:Quicksort returning same vector as passed快速排序返回与传递相同的向量
【发布时间】:2014-07-13 11:37:22
【问题描述】:

我最近开始使用R,并尝试实现快速排序。我正在使用《算法简介(第 3 版)》一书

我正在使用RStudio 并没有看到任何错误,但它返回的向量与传递的向量相同,我是否假设有问题?我相信我的代码与本书的伪代码显示的相匹配。伪代码如下:

Partition(A, p, r)
  x = A[r]
  i = p - 1
  for j = p to r - 1
     if A[j] <= x
       i = i + 1
       swap(A[i], A[j])
  swap(A[i+1], A[r]
  return i + 1

Quicksort(A, p, r)
  if p < r
    q = Partition(A, p, r)
    Quicksort(A, p, q - 1)
    Quicksort(A, q + 1, r)

我比R写了同样的两个函数:

partition <- function(a, p, r) {
    x = a[r]
    i = p - 1
    for (j in p:(r-1)) {
        if (a[j] <= x) {
            i = i + 1
            t = a[i]
            a[i] = a[j]
            a[j] = t
        }
    }
    t = a[i+1]
    a[i+1] = a[r]
    a[r] = t
    i+1
}

quicksort <- function(a, p, r) {
    if (p < r) {
        q = partition(a, p, r)
        quicksort(a, p, q-1)
        quicksort(a, q+1, r)
    }
    a
}

RStudio 中,我获取文件并使用我创建的向量调用它:

> v
[1] 8 5 6 7 4 1 3 2
> quicksort(v, 1, length(v))
[1] 8 5 6 7 4 1 3 2

据我所知,您可以在 R 中执行递归函数,我知道您不能通过引用传递,但这不会调用具有更改向量的相同函数吗?我对为什么它返回传递的相同向量感到困惑。任何帮助将不胜感激。

【问题讨论】:

  • 缺少引用传递意味着您无法使用递归调用更改a

标签: r parameter-passing pass-by-reference pass-by-value


【解决方案1】:

每次您想使用函数更改对象时,都必须返回并分配它。我在两个地方更改了您的代码:partition 函数返回两个项目的列表,向量a 和位置i。在quicksort 中:partition 的结果最初存储在temp 中,其项目分配给aq。此外,您必须将每次更改 a 的结果分配回给它。

partition <- function(a, p, r) {
  x = a[r]
  i = p - 1
  for (j in p:(r-1)) {
    if (a[j] <= x) {
      i = i + 1
      t = a[i]
      a[i] = a[j]   
      a[j] = t
    }
  }
  t = a[i+1]
  a[i+1] = a[r]
  a[r] = t
  list(i = i+1, a = a)
}

quicksort <- function(a, p, r) {
  if (p < r) {
    temp = partition(a, p, r)
    a <- temp$a
    q = temp$i
    a = quicksort(a, p, q-1)
    a = quicksort(a, q+1, r)
  }
  a
}

v = c(8, 5, 6, 7, 4, 1, 3, 2)
quicksort(v, 1, length(v))
## [1] 1 2 3 4 5 6 7 8

干杯,

亚历克斯

【讨论】:

  • 啊!我知道它必须与 R 如何传递值有关它为什么不起作用的特定内容。谢谢!
【解决方案2】:

这是因为您没有在函数quicksortpartition 中修改a。 R(实际上)按值传递。当您修改函数中的值时,您正在修改副本。函数返回后,此修改不会持续存在。

因此,您需要返回分区值而不是在 parition 中进行修改才能使其正常工作。

例如,partition 可以返回两个向量的列表,即两个分区。然后您可以在每个返回的向量上调用quicksort

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 1970-01-01
    • 2011-02-20
    相关资源
    最近更新 更多