我知道,插入排序算法比选择排序更快。 但在我看来,速度的差异太大了。 这是我的两个代码:
#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两个代码都正常工作
选择排序
给定一个向量x,让初始未排序的向量u等于x,和 初始的排序向量是长度为0的向量。
找到你的最小元素,然后将其从u中删除并添加到 结束了。
如果您不为空,请返回步骤2.
插入排序
给定一个向量x,让初始未排序的向量u等于x,和 初始的排序向量是长度为0的向量。
删除u的最后一个元素并将其插入s中,使s仍然是 排序
如果您不为空,请返回步骤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
循环,从而避免在while
或repeat
循环中进行测试。
答案 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)