13.8 Creating Iterators for Complex Data Structures

13.8.1 Implementing an Iterator for a Binary Tree

Definition of the Binary Tree:

#![allow(unused)]
fn main() {
use std::rc::Rc;
use std::cell::RefCell;

#[derive(Debug)]
struct TreeNode {
    value: i32,
    left: Option<Rc<RefCell<TreeNode>>>,
    right: Option<Rc<RefCell<TreeNode>>>,
}
impl TreeNode {
    fn new(value: i32) -> Rc<RefCell<Self>> {
        Rc::new(RefCell::new(TreeNode { value, left: None, right: None }))
    }
}
}

In-Order Iterator Implementation:

#![allow(unused)]
fn main() {
struct InOrderIter {
    stack: Vec<Rc<RefCell<TreeNode>>>,
    current: Option<Rc<RefCell<TreeNode>>>,
}
impl InOrderIter {
    fn new(root: Rc<RefCell<TreeNode>>) -> Self {
        InOrderIter { stack: Vec::new(), current: Some(root) }
    }
}
impl Iterator for InOrderIter {
    type Item = i32;
    fn next(&mut self) -> Option<Self::Item> {
        while let Some(node) = self.current.clone() {
            self.stack.push(node.clone());
            self.current = node.borrow().left.clone();
        }
        if let Some(node) = self.stack.pop() {
            let value = node.borrow().value;
            self.current = node.borrow().right.clone();
            Some(value)
        } else {
            None
        }
    }
}
}

Using the Iterator:

use std::rc::Rc;
use std::cell::RefCell;
#[derive(Debug)]
struct TreeNode {
    value: i32,
    left: Option<Rc<RefCell<TreeNode>>>,
    right: Option<Rc<RefCell<TreeNode>>>,
}
impl TreeNode {
    fn new(value: i32) -> Rc<RefCell<Self>> {
        Rc::new(RefCell::new(TreeNode { value, left: None, right: None }))
    }
}
struct InOrderIter {
    stack: Vec<Rc<RefCell<TreeNode>>>,
    current: Option<Rc<RefCell<TreeNode>>>,
}
impl InOrderIter {
    fn new(root: Rc<RefCell<TreeNode>>) -> Self {
        InOrderIter { stack: Vec::new(), current: Some(root) }
    }
}
impl Iterator for InOrderIter {
    type Item = i32;
    fn next(&mut self) -> Option<Self::Item> {
        while let Some(node) = self.current.clone() {
            self.stack.push(node.clone());
            self.current = node.borrow().left.clone();
        }
        if let Some(node) = self.stack.pop() {
            let value = node.borrow().value;
            self.current = node.borrow().right.clone();
            Some(value)
        } else {
            None
        }
    }
}
fn main() {
    // Building the binary tree
    let root = TreeNode::new(4);
    let left = TreeNode::new(2);
    let right = TreeNode::new(6);
    root.borrow_mut().left = Some(left.clone());
    root.borrow_mut().right = Some(right.clone());
    left.borrow_mut().left = Some(TreeNode::new(1));
    left.borrow_mut().right = Some(TreeNode::new(3));
    right.borrow_mut().left = Some(TreeNode::new(5));
    right.borrow_mut().right = Some(TreeNode::new(7));
    // Creating the iterator
    let iter = InOrderIter::new(root.clone());
    // Collecting the in-order traversal
    let traversal: Vec<i32> = iter.collect();
    println!("{:?}", traversal); // Output: [1, 2, 3, 4, 5, 6, 7]
}