I want to build insertion sort algorithm in r:
Here is my code:
x <- round(runif(1000,1,100)
u <- x
s <- vector(mode="numeric", length=0
for(i in 1:length(u)){
number <-u[i]
u <- u[-i]
for(j in 1:length(s)){
if(length(s) == 0){
s <- c(s,number)
break
}else{
if(s[j]>=number){
s <- append(s,number,j-1)
break
}
}
if(s[length(s)]<number){
s <- c(s,number)
}
}
}
First of all, when length of u = 500 it throws me an error:
Error in if (s[j] >= number) { : missing value where TRUE/FALSE needed
next, it sorted incorrectly(for example it could be more ones than in original vector u, or for example less twos then in original vector u)
So I have two questions:
1)How can we fix that in THIS code?
2)Can you suggest another code, which is more efficient than my?
PS Of course the code should be without sort and order command. Many thanks
Your first question is an easy fix: when you extract a number out of your vector u, what you are really doing, is just drawing a random number from the sample without replacement. So just always take the first value.
# Change the current to this:
number <-u[1]
u <- u[-1]
For your second question: what a fun exercise! My go at it was to just implement the selection sort pseudo-code from Wikipedia , (which you could just do) but with blindfolds: I cannot look into "the bag" of x
but only see my just-drawn item - this I found to be more like what you are asking for.
How do I go about solving this? Simple: I draw a value from x
. Call it my control
variable. Then for every draw I put the new value into a pile of small
if less than (or equal) to control. Otherwise I put it into the large
pile. When I have distributed all values, I do this algorithm again for each pile. I continue until my piles are all of size 1. The implementation of this below.
mysort <- function(x){
if(length(x) <= 1){
return(x) ## If nothing to sort, return itself
}
control <- x[1]
small <- c()
big <- c()
for(test in x[-1]){
if(test <= control){
small <- c(small,test) ## Less than control in small
}
if(test > control){
big <- c(big,test) ## Bigger than control in big
}
}
## Sort the new piles with the same procedure recursively.
small <- mysort(small)
big <- mysort(big)
## Return the improved order
c(small,control,big)
}
mysort(c(2,1,1,2,2,2,3,3,-3,-Inf,Inf,0,pi))
# [1] -Inf -3.000000 0.000000 1.000000 1.000000 2.000000 2.000000 2.000000
# [9] 2.000000 3.000000 3.000000 3.141593 Inf
We can compare speeds with the microbenchmark
package, if we wrap your implementation (without the superfluous while
-loop) in a function yoursort
.
library(microbenchmark)
a <- rnorm(1e3)
microbenchmark(b <- mysort(a),times = 10)
# Unit: milliseconds
# expr min lq mean median uq max neval
# b <- mysort(a) 37.76747 39.2302 41.96171 40.99288 43.07412 47.85377 10
microbenchmark(c <- yoursort(a),times = 10)
# Unit: milliseconds
# expr min lq mean median uq max neval
# c <- yoursort(a) 786.4544 808.2312 861.8072 840.7868 879.4946 1059.913 10
microbenchmark(sort(a),times = 10)
# Unit: microseconds
# expr min lq mean median uq max neval
# sort(a) 192.763 194.384 242.7633 201.1335 263.497 390.386 10
Neither are any match to the already implemented sort
function.
And of course, do they actually do the correct sorting?
any(b != sort(a)) ## Are there any elements that do not match?
# [1] FALSE
any(c != sort(a))
# [1] FALSE
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.