Breadth FIrst Search in RUST

Introduction

Breadth First Search is a fundamental tree traversal algorithm that visits all nodes at the current depth before moving to nodes at the next depth level. In this tutorial, we’ll implement BFS in Rust using a binary tree structure. We’ll break down each component and explore how it works.

1. Setting Up the Tree Structure

use std::collections::VecDeque;

#[derive(Debug)]
struct Tree {
    data: u32,
    left: Option<Box<Tree>>,
    right: Option<Box<Tree>>,
}

Let’s break this down:

2. Implementing Tree Methods

impl Tree {
    fn new(data: u32) -> Self {
        Tree {
            data,
            left: None,
            right: None,
        }
    }

    fn insert_left(&mut self, data: u32) {
        self.left = Some(Box::new(Tree::new(data)));
    }

    fn insert_right(&mut self, data: u32) {
        self.right = Some(Box::new(Tree::new(data)));
    }

3. The BFS Implementation

fn bfs(&self) -> Vec<u32> {
        let mut result = Vec::new();
        let mut queue = VecDeque::new();
        queue.push_back(self);

        while let Some(node) = queue.pop_front() {
            result.push(node.data);
            
            if let Some(left) = &node.left {
                queue.push_back(left);
            }
            if let Some(right) = &node.right {
                queue.push_back(right);
            }
        }
        
        result
    }
  1. Creates a vector to store the traversal result
  2. Initializes a queue with the root node
  3. Continues processing nodes until the queue is empty:
    • Removes and processes the front node
    • Adds its value to the result
    • Queues up the left and right children (if they exist)
  4. Returns the completed traversal

4. Using the Implementation

fn main() {
    // Create the tree structure
    let mut root = Tree::new(1);
    
    // Build left subtree
    root.insert_left(2);
    if let Some(node) = &mut root.left {
        node.insert_left(4);
        node.insert_right(6);
    }
    
    // Build right subtree
    root.insert_right(3);
    if let Some(node) = &mut root.right {
        node.insert_right(5);
    }

    // Perform BFS and print results
    let bfs_result = root.bfs();
    println!("BFS traversal: {:?}", bfs_result);
}
       1
      / \
     2   3
    / \   \
   4   6   5

When we run the BFS, it will visit nodes in this order: 1, 2, 3, 4, 6, 5

Time and Space Complexity

This implementation will visit each node exactly once while keeping at most one level of the tree in the queue at any time.

Conclusion

This Rust implementation of BFS demonstrates how to create a memory-safe, efficient tree traversal algorithm while leveraging Rust’s powerful features like pattern matching and ownership system. The code is both safe and idiomatic, making it a good example of how to implement classical algorithms in Rust.

Leave a Reply

Your email address will not be published. Required fields are marked *