Prime Sieve of Eratosthenes

Sieve of Eratosthenes is an algorithm for generating a list of all prime numbers up to a given integer N. It does this using $$O(n)$$ space and $$O(n \log \log n)$$ time.

The idea
The naive idea to find all primes would be: For each $$m$$ such that $$2\le m\le N$$ if $$m$$ is divisible by some number less than itself, then it is not prime, else it is prime.

The sieve of Eratosthenes turns this idea around, making a simple modification &mdash; instead of going to each number and testing whether it is divisible by a smaller number, it goes to each number and declares all its multiples to be not prime.

Thus, in its simplest version, the algorithm would look like this: Start with an array is_prime[$$2..N$$], all initialized to true. For each $$i$$ such that $$2\le i\le N$$, do  For each multiple $$m$$ of $$i$$ such that $$m\le n$$, "cross out $$m$$", i.e, set is_prime[$$m$$] to false

(At the end, the prime numbers less than $$N$$ are precisely those $$p$$ for which  is true.)

Starting with this simple algorithm, we can make several observations to make it very efficient.


 * 1) If $$m$$ is a multiple of $$i$$ and $$i$$ is a multiple of $$p$$, then $$m$$ is also a multiple of $$p$$. Thus, if $$i$$ has already been crossed out when the algorithm reaches it, we need not go crossing out its multiples, because they would have already been crossed out.
 * 2) If a number $$m$$ is not prime, then it has a factor that is $$\le \sqrt m$$. (This is because if $$m=pq$$, then at least one of $$p$$ and $$q$$ must be $$\le \sqrt m$$.) Thus, any number that is ever crossed out will be crossed out first by a number less than or equal to its square root. Putting this another way, we need not cross out multiples $$m$$ of $$i$$ that are less than $$i^2$$, because if $$m<i^2$$ is composite, it would have already been crossed out by some number smaller than $$i$$. Thus, we can stop when $$i^2$$ exceeds $$N$$.

With these observations, we can write the following algorithm: Start with an array is_prime[$$2..N$$], all initialized to true. For each $$i$$ such that $$2\le i$$ and $$i^2 \le N$$, do  If isprime[$$i$$] is true, For each multiple $$m$$ of $$i$$ such that $$i^2 \le m\le n$$, "cross out $$m$$" &mdash; set is_prime[$$m$$] to false

This algorithm is usually what is meant when "the sieve of Eratosthenes" is mentioned.

Further optimizations?
Note that the multiples of $$i$$ we cross out are precisely $$ik$$, for $$i\le k\le N/i$$. But if $$k$$ is itself not prime, $$ik$$ would already have been crossed out. Thus, we only need to cross out $$ik$$ for those $$k$$ that are still not crossed out. But checking whether or not $$k$$ has been crossed out takes as much time as simply setting  to false, so this does not give us any improvement to our current algorithm. However, we can modify our data structure so that we can incorporate this improvement &mdash; we can keep a data structure that is both an array and a linked list. That is, we keep an array of structures, such that the $$m$$th element contains: a boolean value storing whether $$m$$ is still uncrossed, the next uncrossed value (if this is uncrossed), and the previous uncrossed value (if this is uncrossed). Our structure is simple enough that we can implement it as three arrays. Then, our procedure to cross out $$m$$ would look like this: procedure cross(m) : is_prime[$$m$$]=false next[prev[$$m$$]]=next[$$m$$] prev[next[$$m$$]]=prev[$$m$$] Then, we can write the following algorithm: Start with three arrays is_prime, next and prev Initialize them as: For each $$m$$ is_prime[$$m$$] = [$$m\ge 2$$] prev[$$m$$] = $$m-1$$ next[$$m$$] = $$m+1$$ For each $$i$$ such that $$2\le i$$ and $$i^2 \le N$$, do  If isprime[$$i$$] is true, For each $$k$$, starting at next[$$i$$] and following the nexts, stopping when $$ik>N$$, cross($$ik$$) Whether this will actually lead to either a faster running time or an asymptotically better algorithm is not very clear.

Pseudo-code
func sieve( integer N ) declare is_prime as a boolean array of size N.    for i = 1 to N do is_prime[i] = [i>=2]
 * Sieves up to N.
 * if is_prime[i] is true at the end, then i is a prime.

i = 2 while ( i * i <= N ) if ( is_prime[i] ) for j = i * i to N, in steps of i                     is_prime[j] = false i = i + 1 end func

Optimizations

 * There is no need to store even numbers, as there is only one even prime number. (2, of course.)
 * You can use bitmaps to pack the memory.

Implementations
Implementation in C