The first algorithm producess too evenly spaced numbers
See also low discrepancy series.
Assuming you want 2 random numbers in $[0;1]$. With real uniform data, the chance is 50:50 they are both larger or smaller than 0.5 at the same time. With your approach, the chance is 0. So your data is not uniform.
(As pointed out, this may be a desired property e.g. for stratification. Low-discrepancy series like Halton and Sobel do have their use cases.)
A proper but expensive approach (for real values)
... is to use beta-distributed random numbers. The rank order statistic of the uniform distribution is beta distributed. You can use this to randomly draw the smallest, then the second smallest, ... repeat.
Assuming the data is to be generated in $[0;1]$. The smallest value is $\text{Beta}[1,n]$ distributed. (For subsequent cases, reduce $n$ and rescale to the remaining interval). To generate a general beta random, we would need to generate two Gamma distributed random values. But $1-X\sim \text{Beta}[n, 1]$. Then $-\ln (1-X)\sim \text{Exponential}[n]$. We can sample random numbers from this distribution as $\frac{-\ln(U[0;1])}{n}$ for this.
\begin{align*}
-\ln (1-x) &= \frac{-\ln(1-u)}{n} \\
1-x &= u^\frac{1}{n} \\
x &= 1 - u^\frac{1}{n}
\end{align*}
Which yields the following algorithm:
x = a
for i in range(n, 0, -1):
x += (b-x) * (1 - pow(rand(), 1. / i))
result.append(x)
There may be numerical instabilities involved, and computing pow
and a division for every object may turn out to be slower than sorting.
For integer values you may need to use a different distribution.
Sorting is incredibly cheap, so just use it
But don't bother. Sorting is so ridiculously cheap, so just sort. Over the years, we have well understood how to implement sorting algorithms that sorting doubles is not worth avoiding. Theoretically it's $O(n \log n)$ but the constant term is so ridiculously small in a good implementation that this is the perfect example how useless theoretical complexity results can be. Run a benchmark. Generate 1 million randoms with and without sorting. Run it a few times, and I wouldn't be surprised if quite often the sorting beats the non-sorting, because the cost of sorting will still be much less than your measurement error.
R
. In order to generate an array of $k$ sets of $n$ random numbers over an uniform interval $[a, b]$, the following code works:rand_array <- replicate(k, sort(runif(n, a, b))
. $\endgroup$