Question bank › IB Computer Science › B2 Programming

Recursion and quicksort (HL)

Answer on paper first, then reveal the mark scheme one mark at a time.

1HardHL only5 marks

Consider the recursive function below.

def digit_sum(n):
    if n < 10:
        return n
    return n % 10 + digit_sum(n // 10)

(a) State the base case. [1]

(b) Show the sequence of calls made by digit_sum(4729). [1]

(c) Show the value returned by each call as the recursion unwinds and state the final result. [2]

(d) State what would happen if the base case were removed. [1]

2CoreHL only4 marks

A games studio uses recursive functions in several parts of its software.

(a) Define the term recursion. [1]

(b) Outline the purpose of a base case in a recursive function. [1]

(c) Identify two applications of recursion, other than calculating a factorial. [2]

3CoreHL only4 marks

Consider the following recursive procedure.

def pattern(n):
    if n == 0:
        print("*")
        return
    print(n)
    pattern(n - 1)
    print(n * 10)

(a) State the total number of times pattern is called when pattern(3) is executed, including the first call. [1]

(b) Trace the call pattern(3) and state the complete output, one value per line, in order. [3]

Stuck on Recursion and quicksort (HL)?

Get it sorted in a free 30-minute session

We work through your weakest questions on this topic on Zoom. I reply the same day.

4StandardHL only4 marks

A recursive function count_char(text, ch) returns the number of times the single character ch appears in the string text. For example, count_char("banana", "a") returns 3 and count_char("", "a") returns 0.

Construct the function count_char using recursion. Loops and built-in counting methods (such as count()) must not be used. [4]

5StandardHL only5 marks

The following Python function implements quicksort.

def quicksort(items):
    if len(items) <= 1:
        return items
    pivot = items[0]
    left = [x for x in items[1:] if x < pivot]
    right = [x for x in items[1:] if x >= pivot]
    return quicksort(left) + [pivot] + quicksort(right)

The function is called with the list [42, 17, 63, 8, 55, 29, 71].

(a) State the value of pivot in the first call. [1]

(b) State the contents of left and right in the first call. [2]

(c) Explain why the list returned by the first call is in ascending order, given that the two recursive calls each return a sorted list. [2]

6HardHL only5 marks

The diagram shows the tree of calls made when the quicksort function below is called with [5, 9, 2, 7, 1, 8, 3]. Each box shows the list passed to one call. A left branch is the call on left; a right branch is the call on right.

def quicksort(items):
    if len(items) <= 1:
        return items
    pivot = items[0]
    left = [x for x in items[1:] if x < pivot]
    right = [x for x in items[1:] if x >= pivot]
    return quicksort(left) + [pivot] + quicksort(right)

(a) State the lists represented by A, B, C and D. [2]

(b) State the total number of times quicksort is called. [1]

(c) Explain why the right-hand side of the tree is deeper than the left-hand side. [2]

Each box shows the list passed to that call of quicksort[5, 9, 2, 7, 1, 8, 3][2, 1, 3]A[1]BC[ ][ ]D
7StandardHL only5 marks

A student writes the recursive function below to add the integers from 1 to n.

def sum_to(n):
    if n == 0:
        return 0
    return n + sum_to(n - 1)

sum_to(500) returns 125250, but sum_to(100000) stops with a RecursionError.

(a) Explain why sum_to(100000) fails. [2]

(b) Suggest how the student could calculate the same value for large n without this error. [1]

(c) The student's next task is to draw a fractal tree, in which each branch splits into two smaller branches that look like the whole tree. Explain why recursion is suitable for this task. [2]

8HardHL only5 marks

The quicksort function below always uses the first item as the pivot.

def quicksort(items):
    if len(items) <= 1:
        return items
    pivot = items[0]
    left = [x for x in items[1:] if x < pivot]
    right = [x for x in items[1:] if x >= pivot]
    return quicksort(left) + [pivot] + quicksort(right)

Assume that, in each call that partitions a list, every item other than the pivot is compared with the pivot exactly once.

(a) Calculate the total number of comparisons made when the function sorts the list [1, 2, 3, 4, 5, 6, 7, 8]. Show your working. [2]

(b) Sorting [5, 2, 7, 1, 3, 6, 8, 4] with the same function needs only 13 comparisons. Explain why the list in (a) needs more comparisons. [2]

(c) Suggest a change to the choice of pivot that would avoid this problem. [1]

9StandardHL only5 marks

The recursive function below uses Euclid's algorithm to find the greatest common divisor (GCD) of two positive integers.

def gcd(a, b):
    if b == 0:
        return a
    return gcd(b, a % b)

(a) Trace the call gcd(252, 105) by stating the arguments of every call made, in order. [2]

(b) State the value returned by gcd(252, 105). [1]

(c) State the maximum number of frames for gcd that are on the call stack at the same time during this trace. [1]

(d) Outline what is stored in a stack frame when gcd calls itself. [1]

10StretchHL only7 marks

A sorted list is stored as data = [4, 9, 15, 22, 30, 37, 41, 56] (indices 0 to 7). A programmer writes this recursive binary search, which should return the index of target, or -1 if it is not present.

def bsearch(data, target, low, high):
    mid = (low + high) // 2
    if data[mid] == target:
        return mid
    elif data[mid] < target:
        return bsearch(data, target, mid, high)
    else:
        return bsearch(data, target, low, mid - 1)

(a) Trace bsearch(data, 37, 0, 7), stating the values of low, high and mid in each call, and state the value returned. [2]

(b) Explain what happens when bsearch(data, 50, 0, 7) is executed. [2]

(c) Construct a corrected version of bsearch. [3]

Stuck on this topic?

Book a free 30-minute session on WhatsApp and we'll find exactly which step is costing you the marks. Or build a timed paper on it.

Free 30-minute session