Bird
Raised Fist0
DSA Rustprogramming~20 mins

Heap Extract Min or Max Bubble Down in DSA Rust - Practice Problems & Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Heap Mastery Badge
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the state of the max-heap array after extracting the max element?
Consider a max-heap represented as an array: [50, 30, 40, 10, 20]. After extracting the max element (50) and performing bubble down, what is the resulting heap array?
DSA Rust
fn bubble_down(heap: &mut Vec<i32>, mut index: usize) {
    let length = heap.len();
    loop {
        let left = 2 * index + 1;
        let right = 2 * index + 2;
        let mut largest = index;

        if left < length && heap[left] > heap[largest] {
            largest = left;
        }
        if right < length && heap[right] > heap[largest] {
            largest = right;
        }
        if largest == index {
            break;
        }
        heap.swap(index, largest);
        index = largest;
    }
}

fn extract_max(heap: &mut Vec<i32>) -> Option<i32> {
    if heap.is_empty() {
        return None;
    }
    let max = heap[0];
    let last = heap.pop().unwrap();
    if !heap.is_empty() {
        heap[0] = last;
        bubble_down(heap, 0);
    }
    Some(max)
}

fn main() {
    let mut heap = vec![50, 30, 40, 10, 20];
    let max = extract_max(&mut heap);
    println!("{:?}", heap);
}
A[40, 30, 20, 10]
B[40, 20, 30, 10]
C[30, 20, 40, 10]
D[30, 40, 20, 10]
Attempts:
2 left
💡 Hint
Remember that after removing the root, the last element moves to the root and then bubbles down to restore max-heap property.
❓ Predict Output
intermediate
2:00remaining
What is the min-heap array after extracting the min element and bubbling down?
Given a min-heap array: [5, 10, 15, 20, 25]. After extracting the min element (5) and performing bubble down, what is the resulting heap array?
DSA Rust
fn bubble_down_min(heap: &mut Vec<i32>, mut index: usize) {
    let length = heap.len();
    loop {
        let left = 2 * index + 1;
        let right = 2 * index + 2;
        let mut smallest = index;

        if left < length && heap[left] < heap[smallest] {
            smallest = left;
        }
        if right < length && heap[right] < heap[smallest] {
            smallest = right;
        }
        if smallest == index {
            break;
        }
        heap.swap(index, smallest);
        index = smallest;
    }
}

fn extract_min(heap: &mut Vec<i32>) -> Option<i32> {
    if heap.is_empty() {
        return None;
    }
    let min = heap[0];
    let last = heap.pop().unwrap();
    if !heap.is_empty() {
        heap[0] = last;
        bubble_down_min(heap, 0);
    }
    Some(min)
}

fn main() {
    let mut heap = vec![5, 10, 15, 20, 25];
    let min = extract_min(&mut heap);
    println!("{:?}", heap);
}
A[15, 20, 10, 25]
B[10, 15, 20, 25]
C[15, 10, 20, 25]
D[10, 20, 15, 25]
Attempts:
2 left
💡 Hint
After removing the root, the last element moves to the root and bubbles down to maintain min-heap property.
🔧 Debug
advanced
2:00remaining
Identify the bug in this bubble down implementation for max-heap
This Rust function is intended to bubble down the root element in a max-heap after extraction. What is the bug causing incorrect heap structure?
DSA Rust
fn bubble_down(heap: &mut Vec<i32>, mut index: usize) {
    let length = heap.len();
    while index < length {
        let left = 2 * index + 1;
        let right = 2 * index + 2;
        let mut largest = index;

        if left < length && heap[left] > heap[largest] {
            largest = left;
        }
        if right < length && heap[right] > heap[largest] {
            largest = right;
        }
        if largest == index {
            break;
        }
        heap.swap(index, largest);
        // Missing update of index here
    }
}
AThe comparison operators should be < instead of > for max-heap bubble down.
BThe function uses a while loop instead of a for loop, which is incorrect for bubble down.
CThe index variable is not updated after swapping, causing an infinite loop or no progress.
DThe function should pop the last element before bubbling down, but it doesn't.
Attempts:
2 left
💡 Hint
Check if the loop variable changes after swapping elements.
❓ Predict Output
advanced
2:00remaining
What is the heap array after extracting max from this heap?
Given the max-heap array: [100, 50, 90, 20, 40, 80, 85], after extracting the max element and bubbling down, what is the resulting heap array?
DSA Rust
fn bubble_down(heap: &mut Vec<i32>, mut index: usize) {
    let length = heap.len();
    loop {
        let left = 2 * index + 1;
        let right = 2 * index + 2;
        let mut largest = index;

        if left < length && heap[left] > heap[largest] {
            largest = left;
        }
        if right < length && heap[right] > heap[largest] {
            largest = right;
        }
        if largest == index {
            break;
        }
        heap.swap(index, largest);
        index = largest;
    }
}

fn extract_max(heap: &mut Vec<i32>) -> Option<i32> {
    if heap.is_empty() {
        return None;
    }
    let max = heap[0];
    let last = heap.pop().unwrap();
    if !heap.is_empty() {
        heap[0] = last;
        bubble_down(heap, 0);
    }
    Some(max)
}

fn main() {
    let mut heap = vec![100, 50, 90, 20, 40, 80, 85];
    let max = extract_max(&mut heap);
    println!("{:?}", heap);
}
A[90, 50, 85, 20, 40, 80]
B[90, 50, 80, 20, 40, 85]
C[85, 50, 90, 20, 40, 80]
D[85, 50, 80, 20, 40, 90]
Attempts:
2 left
💡 Hint
After removing 100, last element 85 moves to root. Bubble down swaps with largest child each step.
🧠 Conceptual
expert
2:00remaining
Why is bubble down necessary after extracting the root in a heap?
After extracting the root element from a heap (min or max), why must we perform the bubble down operation?
ABecause bubble down sorts the entire heap array to maintain order.
BBecause the last element moved to the root may violate the heap property, so bubble down restores the heap order.
CBecause bubble down removes duplicate elements from the heap after extraction.
DBecause bubble down adds new elements to the heap to keep it balanced.
Attempts:
2 left
💡 Hint
Think about what happens when the last element replaces the root.

Practice

(1/5)
1. What is the main purpose of the bubble down operation in a min-heap after extracting the minimum element?
easy
A. To insert a new element at the bottom of the heap
B. To remove all elements smaller than the root
C. To swap the last element with the root without any further changes
D. To restore the heap property by moving the root element down to its correct position

Solution

  1. Step 1: Understand extract-min operation

    Extracting the minimum removes the root, so the last element moves to the root.
  2. Step 2: Purpose of bubble down

    Bubble down moves this new root down to restore the min-heap property by swapping with smaller children.
  3. Final Answer:

    To restore the heap property by moving the root element down to its correct position -> Option D
  4. Quick Check:

    Bubble down fixes heap after extract-min [OK]
Hint: Bubble down fixes heap from root after extract-min [OK]
Common Mistakes:
  • Thinking bubble down inserts new elements
  • Assuming bubble down removes elements
  • Confusing bubble down with bubble up
2. Which of the following Rust function signatures correctly represents a bubble down operation for a min-heap stored in a vector?
easy
A. fn bubble_down(&heap: Vec<i32>, index: usize)
B. fn bubble_down(heap: &mut Vec<i32>, index: usize)
C. fn bubble_down(heap: Vec<i32>, index: usize) -> Vec<i32>
D. fn bubble_down(heap: &Vec<i32>, index: usize)

Solution

  1. Step 1: Identify mutability needs

    Bubble down modifies the heap, so it needs a mutable reference to the vector.
  2. Step 2: Check parameter types

    fn bubble_down(heap: &mut Vec<i32>, index: usize) uses &mut Vec<i32>, allowing in-place changes without ownership transfer.
  3. Final Answer:

    fn bubble_down(heap: &mut Vec<i32>, index: usize) -> Option B
  4. Quick Check:

    Mutable reference needed for in-place heap changes [OK]
Hint: Use &mut Vec for in-place heap modification [OK]
Common Mistakes:
  • Passing Vec by value causing ownership move
  • Using immutable references when mutation is needed
  • Incorrect parameter syntax
3. Consider the following Rust code snippet for a min-heap stored in a vector:
let mut heap = vec![1, 3, 6, 5, 9, 8];
heap[0] = heap.pop().unwrap();
bubble_down(&mut heap, 0);
println!("{:?}", heap);
If bubble_down correctly restores the min-heap property, what will be the printed vector?
medium
A. [3, 5, 8, 6, 9]
B. [6, 3, 8, 5, 9]
C. [3, 5, 6, 8, 9]
D. [5, 3, 6, 8, 9]

Solution

  1. Step 1: Understand initial heap and pop

    Initial heap: [1,3,6,5,9,8]. After pop(), last element 8 is removed and placed at root: heap[0] = 8, heap = [8,3,6,5,9]
  2. Step 2: Bubble down from root

    Compare 8 with children 3 and 6; smallest is 3, swap 8 and 3: [3,8,6,5,9]. Next, bubble down 8 at index 1 with children 5 and 9; smallest is 5, swap: [3,5,6,8,9]. No further swaps needed.
  3. Final Answer:

    [3, 5, 6, 8, 9] -> Option C
  4. Quick Check:

    Bubble down swaps to restore min-heap [OK]
Hint: Replace root with last, then bubble down to fix heap [OK]
Common Mistakes:
  • Not swapping with smallest child
  • Stopping bubble down too early
  • Incorrect pop and root replacement
4. Given this Rust bubble down function snippet for a max-heap, identify the bug:
fn bubble_down(heap: &mut Vec<i32>, mut index: usize) {
    let len = heap.len();
    loop {
        let left = 2 * index + 1;
        let right = 2 * index + 2;
        let mut largest = index;
        if left < len && heap[left] > heap[largest] {
            largest = left;
        }
        if right < len && heap[right] > heap[largest] {
            largest = right;
        }
        if largest == index {
            break;
        }
        heap.swap(index, largest);
        // Missing update of index here
    }
}
medium
A. The index variable is not updated after swapping, causing an infinite loop
B. The function uses a min-heap condition instead of max-heap
C. The left and right child indices are calculated incorrectly
D. The swap function is used incorrectly

Solution

  1. Step 1: Analyze loop behavior

    After swapping, the index must move to the child's position to continue bubbling down.
  2. Step 2: Identify missing update

    The code does not update index = largest after swap, so loop repeats with same index causing infinite loop.
  3. Final Answer:

    The index variable is not updated after swapping, causing an infinite loop -> Option A
  4. Quick Check:

    Update index after swap to continue bubble down [OK]
Hint: Always update index after swap in bubble down loop [OK]
Common Mistakes:
  • Forgetting to update index after swap
  • Mixing min-heap and max-heap conditions
  • Incorrect child index calculations
5. You have a max-heap represented as [50, 30, 40, 10, 20, 35]. After extracting the maximum element (50), you replace the root with the last element and perform bubble down. What is the final heap array after bubble down completes?
hard
A. [40, 30, 35, 10, 20]
B. [40, 30, 10, 20, 35]
C. [35, 30, 40, 10, 20]
D. [35, 30, 20, 10, 40]

Solution

  1. Step 1: Replace root with last element

    Remove 50, move last element 35 to root: [35, 30, 40, 10, 20]
  2. Step 2: Bubble down from root

    Compare 35 with children 30 and 40; largest is 40, swap: [40, 30, 35, 10, 20]. Next, bubble down 35 at index 2 with children none (leaf), stop.
  3. Final Answer:

    [40, 30, 35, 10, 20] -> Option A
  4. Quick Check:

    Bubble down swaps root with largest child until heap restored [OK]
Hint: Replace root with last, bubble down swapping with largest child [OK]
Common Mistakes:
  • Not swapping with largest child
  • Stopping bubble down too early
  • Incorrect root replacement
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard