选择排序与插入排序。速度差异很大

时间:2016-06-21 10:54:15

标签: r sorting

我知道,插入排序算法比选择排序更快。 但在我看来,速度的差异太大了。 这是我的两个代码:

#Selection sort algorithm:
u <- round(runif(100,1,100))
selection_sort <- function(x){
    s <- vector('numeric')
    while(length(x) != 0){
        minimum <- x[1]
        for(i in 1:length(x)){
            ifelse(x[i]<minimum,minimum <- x[i],next())
        }
        x <- x[-match(minimum,x)]
        s <- c(s,minimum)
    }
    s
}

#Insertion sort algorithm:
u <- round(runif(100,1,100))
insertion_sort <- function(x){
    s <- vector('numeric')
    while(length(x) !=0){
        num <- x[1]
        x <- x[-match(num,x)]
        if(length(s) == 0){
            s <- c(s,num)
        } else{
            for(i in 1:length(s)){
                if(s[i]>=num){
                    s <- append(s,num,i-1)
                    break
                }
            }
            if(s[length(s)]<num){
                s <- c(s,num)
            }
        }
    }
}

我通过microbenchmark推荐检查了我的代码速度,得到了以下结果:

microbenchmark(b <- insertion_sort(u),times = 10)
expr      min       lq     mean   median       uq      max neval
2.793573 2.873704 3.159338 2.920087 3.136996 5.066089    10


microbenchmark(b <- selection_sort(u),times = 10)
expr      min       lq    mean   median       uq      max neval
21.50502 21.61436 31.7791 22.71371 40.64712 68.17705    10

这种速度差异好吗? 我知道,也许我的代码效率不高。如果这种差异不好,我该如何纠正呢?

P.S两个代码都正常工作

选择排序

  1. 给定一个向量x,让初始未排序的向量u等于x,和 初始的排序向量是长度为0的向量。

  2. 找到你的最小元素,然后将其从u中删除并添加到 结束了。

  3. 如果您不为空,请返回步骤2.

  4. 插入排序

    1. 给定一个向量x,让初始未排序的向量u等于x,和 初始的排序向量是长度为0的向量。

    2. 删除u的最后一个元素并将其插入s中,使s仍然是 排序

    3. 如果您不为空,请返回步骤2.

2 个答案:

答案 0 :(得分:6)

这是在R中实现选择排序的一种(相对)有效的方式:

selection_sort <- function(x){
  s <- numeric(length(x))
  for (i in seq_len(length(x))) {
    ind <- which.min(x)
    s[i] <- x[ind]
    x[ind] <- NA
  }
  s
}

set.seed(42)
v <- rnorm(10)
selection_sort(v)
#[1] -0.56469817 -0.10612452 -0.09465904 -0.06271410  0.36312841  0.40426832  0.63286260  1.37095845  1.51152200  2.01842371

请注意我如何避免调整向量的大小以及如何使用for循环,从而避免在whilerepeat循环中进行测试。

答案 1 :(得分:1)

类似的想法(由@Roland提供)也可以在JuliaLang中实现(包括此选项,因为迭代在JuliaLang中通常很快)

srand(42)
v =  randn(10)
v1 = deepcopy(v)
function sel_sort(x)
   s = zeros(length(x))
   for i in eachindex(x)
      ind = indmin(x)
      s[i] = x[ind]
      x[ind] = maximum(x) + 1
    end
  s
end


sel_sort(v)
#10-element Array{Float64,1}:
#-2.64199
#-1.1449
#-0.556027
#-0.468606
#-0.444383
#-0.299484
# 0.0271553
# 0.156143
# 1.00331
# 1.77786

此外,我们还可以使用已经实现的排序算法

sort(v1, alg = InsertionSort)
# 10-element Array{Float64,1}:
#-2.64199
#-1.1449
#-0.556027
#-0.468606
#-0.444383
#-0.299484
#0.0271553
#0.156143
#1.00331
#1.77786

sort!更改原始矢量。

sort!(v1, alg = InsertionSort)