Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Tree validation

Below we present the implementation of an iterative algoritm to validate the binary search tree. The idea here is to go the left most node - and then traverse the tree in order. When traversing tree in order - we expect every next element to be bigger than the previous element and lesser than the root element. When we cross the root - we want every element be greater than the root and its previous element.

###Following function achieves the same:

//Validate the if the tree is valid
    //We use an interative process here
    pub fn validate(&self) -> bool {
        match self.0 {
            None => true,
            Some(ref root) => {
                let mut current = Some(Rc::clone(root));
                let mut stack = Vec::new();
                let mut previous = None;
                let mut crossed_root = false;
                let mut first = Some(false);
                while current.is_some() || !stack.is_empty() {
                    while current.is_some() {
                        stack.push(current.as_ref().cloned());
                        current = current.and_then(|inner| inner.borrow().left_node());
                    }
                    current = stack.pop().and_then(|popped| popped);
                    //Has moved to the right side of the tree
                    if !crossed_root {
                        crossed_root = current.as_ref().map(|curr| Rc::ptr_eq(curr, root)).unwrap();
                        if let Some(first) = first.as_mut() {
                            *first = crossed_root;
                        }
                    }
                    match previous {
                        None => previous = current.as_ref().map(Rc::clone),
                        Some(ref prev) => match current.as_ref().map(|curr| {
                            (
                                crossed_root,
                                &mut first,
                                curr.borrow().key() > prev.borrow().key(),
                                curr.borrow().key() < root.borrow().key(),
                            )
                        }) {
                            Some((false, Some(false), true, true)) => {
                                previous = current.as_ref().map(Rc::clone)
                            }
                            Some((true, Some(true), true, false)) => {
                                if let Some(first) = first.as_mut() {
                                    *first = false;
                                }
                                previous = current.as_ref().map(Rc::clone)
                            }
                            Some((true, Some(false), true, false)) => {
                                previous = current.as_ref().map(Rc::clone)
                            }
                            _ => return false,
                        },
                    }
                    current = current.and_then(|inner| inner.borrow().right_node());
                }
                true
            }
        }
    }