Bird
Raised Fist0
DSA Rustprogramming

Create a Binary Tree Manually in DSA Rust

Choose your learning style10 modes available
Mental Model
A binary tree is a structure where each node holds a value and can connect to up to two child nodes, left and right. Creating it manually means building each node and linking them step by step.
Analogy: Think of a family tree where each person can have up to two children. You create each person and then say who their children are, building the tree from the top down.
    1
   / \
  2   3
 / \
4   5

(1 is root, 2 and 3 are children of 1, 4 and 5 are children of 2)
Dry Run Walkthrough
Input: Create a binary tree with root 1, left child 2, right child 3, and 2's children 4 (left) and 5 (right).
Goal: Build the tree node by node and link children correctly.
Step 1: Create root node with value 1
1 (root) -> left: null, right: null
Why: Start with the root node as the base of the tree
Step 2: Create node with value 2 and link as left child of root
1 -> left: 2, right: null
2 -> left: null, right: null
Why: Add left child to root to build left subtree
Step 3: Create node with value 3 and link as right child of root
1 -> left: 2, right: 3
2 -> left: null, right: null
3 -> left: null, right: null
Why: Add right child to root to complete root's children
Step 4: Create node with value 4 and link as left child of node 2
1 -> left: 2, right: 3
2 -> left: 4, right: null
3 -> left: null, right: null
4 -> left: null, right: null
Why: Build left subtree of node 2
Step 5: Create node with value 5 and link as right child of node 2
1 -> left: 2, right: 3
2 -> left: 4, right: 5
3 -> left: null, right: null
4 -> left: null, right: null
5 -> left: null, right: null
Why: Complete children of node 2
Result:
1 -> left: 2, right: 3
2 -> left: 4, right: 5
3 -> left: null, right: null
4 -> left: null, right: null
5 -> left: null, right: null
Annotated Code
DSA Rust
use std::rc::Rc;
use std::cell::RefCell;

// Define a binary tree node
#[derive(Debug)]
struct TreeNode {
    val: i32,
    left: Option<Rc<RefCell<TreeNode>>>,
    right: Option<Rc<RefCell<TreeNode>>>,
}

impl TreeNode {
    fn new(val: i32) -> Rc<RefCell<TreeNode>> {
        Rc::new(RefCell::new(TreeNode { val, left: None, right: None }))
    }
}

fn main() {
    // Step 1: Create root node with value 1
    let root = TreeNode::new(1);

    // Step 2: Create node 2 and link as left child of root
    let node2 = TreeNode::new(2);
    root.borrow_mut().left = Some(node2.clone());

    // Step 3: Create node 3 and link as right child of root
    let node3 = TreeNode::new(3);
    root.borrow_mut().right = Some(node3.clone());

    // Step 4: Create node 4 and link as left child of node 2
    let node4 = TreeNode::new(4);
    node2.borrow_mut().left = Some(node4);

    // Step 5: Create node 5 and link as right child of node 2
    let node5 = TreeNode::new(5);
    node2.borrow_mut().right = Some(node5);

    // Print the tree structure in preorder to verify
    fn preorder(node: &Option<Rc<RefCell<TreeNode>>>) {
        if let Some(n) = node {
            print!("{} ", n.borrow().val); // visit node
            preorder(&n.borrow().left);    // visit left subtree
            preorder(&n.borrow().right);   // visit right subtree
        }
    }

    preorder(&Some(root));
    println!();
}
let root = TreeNode::new(1);
create root node with value 1
let node2 = TreeNode::new(2); root.borrow_mut().left = Some(node2.clone());
create node 2 and link as left child of root
let node3 = TreeNode::new(3); root.borrow_mut().right = Some(node3.clone());
create node 3 and link as right child of root
let node4 = TreeNode::new(4); node2.borrow_mut().left = Some(node4);
create node 4 and link as left child of node 2
let node5 = TreeNode::new(5); node2.borrow_mut().right = Some(node5);
create node 5 and link as right child of node 2
fn preorder(node: &Option<Rc<RefCell<TreeNode>>>) { ... }
traverse tree preorder to print nodes
preorder(&Some(root));
start preorder traversal from root
OutputSuccess
1 2 4 5 3
Complexity Analysis
Time: O(n) because printing the tree visits each node once
Space: O(n) because each node is stored separately in memory
vs Alternative: Manual creation is straightforward but verbose; automated tree builders or recursive insertions can be shorter but less explicit
Edge Cases
Empty tree (no nodes)
No nodes to create or link; root is None
DSA Rust
N/A - code assumes root node creation
Single node tree
Only root node exists with no children
DSA Rust
let root = TreeNode::new(1);
When to Use This Pattern
When you need to build a binary tree from scratch with known values and structure, manually creating nodes and linking children is the direct approach.
Common Mistakes
Mistake: Forgetting to clone Rc when linking the same node multiple times
Fix: Use .clone() on Rc pointers to share ownership safely
Mistake: Trying to mutate nodes without using RefCell
Fix: Wrap nodes in RefCell to allow interior mutability
Summary
Manually creating a binary tree means making each node and linking left and right children explicitly.
Use this when you know the exact tree structure and want full control over node connections.
The key insight is that each node holds pointers to children, and you build the tree by connecting these pointers step by step.

Practice

(1/5)
1. What is the main purpose of creating a binary tree manually in Rust using structs and references?
easy
A. To store data in a single linear sequence
B. To create a list of numbers in ascending order
C. To build a tree structure where each node can have up to two children
D. To perform arithmetic operations on numbers

Solution

  1. Step 1: Understand binary tree structure

    A binary tree is a data structure where each node has at most two children, called left and right.
  2. Step 2: Purpose of manual creation in Rust

    Manually creating a binary tree in Rust involves defining nodes and linking them with references to build this two-child structure.
  3. Final Answer:

    To build a tree structure where each node can have up to two children -> Option C
  4. Quick Check:

    Binary tree = nodes with up to two children [OK]
Hint: Binary tree nodes have max two children [OK]
Common Mistakes:
  • Confusing binary tree with linked list
  • Thinking binary tree nodes have more than two children
  • Assuming binary tree stores data linearly
2. Which of the following Rust code snippets correctly defines a binary tree node struct with optional left and right children?
easy
A. struct Node { value: i32, left: Option, right: Option }
B. struct Node { value: i32, left: Node, right: Node }
C. struct Node { value: i32, left: Box<Node>, right: Box<Node> }
D. struct Node { value: i32, left: &Node, right: &Node }

Solution

  1. Step 1: Check for optional children

    Binary tree nodes may or may not have children, so left and right should be Option types.
  2. Step 2: Use Box for heap allocation

    Since nodes refer to other nodes recursively, Box is needed to allocate on heap and avoid infinite size.
  3. Final Answer:

    struct Node { value: i32, left: Option, right: Option } -> Option A
  4. Quick Check:

    Optional boxed children = correct node struct [OK]
Hint: Use Option for children in Rust [OK]
Common Mistakes:
  • Using direct Node type causing infinite size error
  • Not wrapping children in Option for nullable links
  • Using references without lifetimes causing errors
3. Given the following Rust code that manually creates a binary tree, what will be printed by the println! statement?
struct Node {
    value: i32,
    left: Option,
    right: Option,
}

fn main() {
    let leaf = Node { value: 3, left: None, right: None };
    let root = Node {
        value: 1,
        left: Some(Box::new(leaf)),
        right: None,
    };
    println!("{}", root.left.as_ref().unwrap().value);
}
medium
A. 1
B. 3
C. None
D. Compilation error

Solution

  1. Step 1: Understand tree structure

    The root node has value 1, with left child node value 3 and no right child.
  2. Step 2: Trace the println! statement

    root.left is Some(Box<Node>) containing leaf with value 3, so unwrap().value prints 3.
  3. Final Answer:

    3 -> Option B
  4. Quick Check:

    Access left child's value = 3 [OK]
Hint: Access left child with unwrap() to get value [OK]
Common Mistakes:
  • Printing root value instead of left child's
  • Forgetting to unwrap Option before accessing value
  • Confusing left and right children
4. The following Rust code attempts to create a binary tree node but fails to compile. What is the error and how to fix it?
struct Node {
    value: i32,
    left: Option,
    right: Option,
}

fn main() {
    let node = Node {
        value: 5,
        left: None,
        right: None,
    };
    let root = Node {
        value: 10,
        left: Some(node),
        right: None,
    };
}
medium
A. Error: cannot move `node` into `Some` because `node` does not implement Copy; fix by wrapping node in Box::new()
B. Error: missing semicolon after node declaration; fix by adding semicolon
C. Error: left field must be a reference; fix by using &node
D. No error; code compiles successfully

Solution

  1. Step 1: Identify the error cause

    left field expects Option, but Some(node) tries to move Node directly, causing type mismatch.
  2. Step 2: Fix by boxing node

    Wrap node in Box::new(node) inside Some to match Option type.
  3. Final Answer:

    Error: cannot move `node` into `Some` because `node` does not implement Copy; fix by wrapping node in Box::new() -> Option A
  4. Quick Check:

    Box node before Some to fix type error [OK]
Hint: Wrap node in Box::new() for Option [OK]
Common Mistakes:
  • Trying to use node directly without Box
  • Using references without lifetimes
  • Ignoring compiler type mismatch errors
5. You want to manually create a binary tree in Rust with root value 10, left child 5, and right child 15. Which code snippet correctly builds this tree and prints the right child's value?
hard
A. fn main() { struct Node { value: i32, left: Option, right: Option, } let left = Node { value: 5, left: None, right: None }; let right = Node { value: 15, left: None, right: None }; let root = Node { value: 10, left: Some(left), right: Some(right), }; println!("{}", root.right.as_ref().unwrap().value); }
B. fn main() { struct Node { value: i32, left: Option, right: Option, } let root = Node { value: 10, left: Some(Node { value: 5, left: None, right: None }), right: Some(Node { value: 15, left: None, right: None }), }; println!("{}", root.right.unwrap().value); }
C. fn main() { struct Node { value: i32, left: Option, right: Option, } let root = Node { value: 10, left: None, right: None, }; println!("{}", root.right.unwrap().value); }
D. fn main() { struct Node { value: i32, left: Option, right: Option, } let left = Box::new(Node { value: 5, left: None, right: None }); let right = Box::new(Node { value: 15, left: None, right: None }); let root = Node { value: 10, left: Some(left), right: Some(right), }; println!("{}", root.right.as_ref().unwrap().value); }

Solution

  1. Step 1: Check node creation and boxing

    Children must be boxed nodes wrapped in Some to match Option type.
  2. Step 2: Verify printing right child's value

    Use root.right.as_ref().unwrap().value to safely access right child's value 15.
  3. Final Answer:

    Code in option D correctly creates and prints right child's value 15 -> Option D
  4. Quick Check:

    Box children and unwrap Option to print value [OK]
Hint: Box children nodes and unwrap Option to access value [OK]
Common Mistakes:
  • Not boxing children nodes causing type errors
  • Using unwrap() directly on Option without as_ref()
  • Creating nodes without children or wrong types
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