This algorithm is known as the Sieve of Eratosthenes. Here is a Python implementation of the algorithm:

```python
def sieve_of_eratosthenes(x):
    # Create a list of boolean values, all initially set to True
    sieve = [True] * (x + 1)
    sieve[0:2] = [False, False]  # 0 and 1 are not prime numbers

    # Iterate from 2 to the square root of x
    for current_prime in range(2, int(x ** 0.5) + 1):
        # If the current number is prime, mark its multiples as not prime
        if sieve[current_prime]:
            for multiple in range(current_prime ** 2, x + 1, current_prime):
                sieve[multiple] = False

    # Return a list of all prime numbers in the range
    return [num for num, is_prime in enumerate(sieve) if is_prime]

# Example usage:
x = 30
prime_numbers = sieve_of_eratosthenes(x)
print("Prime numbers up to", x, ":", prime_numbers)
```

This code creates a list of boolean values, where `sieve[i]` represents whether `i` is a prime number or not. It then iterates over the list, marking the multiples of each prime number as not prime. Finally, it returns a list of all prime numbers in the range.

Note that this implementation uses a recursive approach, but it's not a traditional recursive function. Instead, it uses a loop to iterate over the list and mark the multiples of each prime number. This is because Python has a recursion limit, and using a loop is generally more efficient and scalable.

The time complexity of the Sieve of Eratosthenes is O(n log log n), making it a very efficient algorithm for finding prime numbers up to a given number.