R中的Quicksort:如何打印中间步骤?

时间:2013-07-11 22:23:43

标签: r algorithm sorting quicksort

我承认我的算法知识不是很好。我使用基本递归在R中编写了一个quicksort函数。我的问题是,如何修改此算法以在每次迭代之间显示中间向量。我知道有一个聪明的方法来跟踪你的支点,但我很难自己解决这个问题。

qs <- function(vec) {

  if(length(vec) > 1) {

    pivot <- vec[1]

    low <- qs(vec[vec < pivot])
    mid <- vec[vec == pivot]
    high <- qs(vec[vec > pivot])

    c(low, mid, high)


  }

  else vec

}

3 个答案:

答案 0 :(得分:1)

PS:我不确定,但是根据R如何使用逻辑数组进行下标,您的实现可能效率非常低。

如果不在当前状态下花费太多内存(即使用递归),就无法做到这一点。

如果你想保持递归: 这是深度优先的方法。初始化一个数组数组。第一个索引是深度,相应的数组将为您提供该深度的状态。跟踪深度(即将深度作为参数)并将子阵列附加到相应的深度。

代码:

printableList = Array of empty arrays 
qs <- function(vec, depth) {
printableList[depth] = printableList[depth] + vec

  if(length(vec) > 1) {
    pivot <- vec[1]
    low <- qs(vec[vec < pivot], depth+1)
    mid <- vec[vec == pivot]
    high <- qs(vec[vec > pivot], depth+1)

    c(low, mid, high)
  }
  else vec
}

<强>可替换地: 您还可以将整个事物作为广度优先的方法来实现。你将不得不用队列来实现整个事情。在这里,由于您逐层处理子问题,您只需要打印它们。

答案 1 :(得分:0)

正如@dickoa所说,使用print。但是,如果您正在使用GUI,则默认情况下会打印输出,直到函数返回为止。您可以使用flush.console强制打印输出。

qs <- function(vec) {

  # print input vector
  print(vec); flush.console()

  if(length(vec) > 1) {

    pivot <- vec[1]

    low <- qs(vec[vec < pivot])
    mid <- vec[vec == pivot]
    high <- qs(vec[vec > pivot])

    c(low, mid, high)


  }

  else vec

}

示例运行:

> z <- sample(10)
> qs(z)
 [1]  2  6  1  4  8  5  9  7  3 10
[1] 1
[1]  6  4  8  5  9  7  3 10
[1] 4 5 3
[1] 3
[1] 5
[1]  8  9  7 10
[1] 7
[1]  9 10
integer(0)
[1] 10
 [1]  1  2  3  4  5  6  7  8  9 10

答案 2 :(得分:0)

您可以通过在每个函数调用时传递整个向量以及“start”和“end”参数来描述您当前正在排序的向量片段。这是我第一次尝试这样做。也许你可以写一个更优雅的版本?

qs<-function(vec,start=1,finish=length(vec)) {
  if (finish>start) {
    pivot<-vec[start]
    N<-length(vec)
    window<-((1:N)>=start) & ((1:N)<=finish)
    low_part<-vec[(vec<pivot) & window]
    mid_part<-vec[(vec==pivot) & window]
    high_part<-vec[(vec>pivot) & window]

    if (start>1) cat(vec[1:(start-1)],"| ")
    cat(low_part,">>>",mid_part,"<<<",high_part)
    if (finish<N) cat(" |",vec[(finish+1):N])
    cat("\n")

    vec[window]<-c(low_part,mid_part,high_part)
    if (length(low_part)>0) {
      low_top<-start+length(low_part)-1
      vec[start:low_top]<-qs(vec,start,low_top)[start:low_top]
    }
    if (length(high_part)>0) {
      high_bottom<-finish-length(high_part)+1
      vec[high_bottom:finish]<-qs(vec,high_bottom,finish)[high_bottom:finish]
    }
  }
  return(vec)
}

qs(sample(1:30,replace=TRUE))