Start writing functions for finding a node within the tree

This commit is contained in:
Savanni D'Gerinel 2024-04-09 22:55:33 -04:00
parent 0aecaee760
commit 511f1080a7
1 changed files with 48 additions and 0 deletions

View File

@ -9,6 +9,10 @@ use std::{
rc::Rc, rc::Rc,
}; };
// I need to take what I learned about linked lists and about the other Tree data structure, and
// apply it here with arena allocation.
//
// Also, smarter node allocation and pointer handling in order to avoid clones.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub enum Tree<T> { pub enum Tree<T> {
#[default] #[default]
@ -55,6 +59,16 @@ impl<T> Tree<T> {
None None
} }
// Do a depth-first-search in order to get the path to a node. Start with a naive recursive
// implementation, then switch to a stack-based implementation in order to avoid exceeding the
// stack.
pub fn path_to<F>(&self, f: F) -> Vec<Node<T>>
where
F: FnOnce(&T) -> bool + Copy,
{
unimplemented!()
}
/// Convert each node of a tree from type T to type U /// Convert each node of a tree from type T to type U
pub fn map<F, U>(&self, op: F) -> Tree<U> pub fn map<F, U>(&self, op: F) -> Tree<U>
where where
@ -146,6 +160,13 @@ impl<T> Node<T> {
} }
} }
impl<T: PartialEq> PartialEq for Node<T> {
fn eq(&self, other: &Node<T>) -> bool {
self.0.borrow().value == other.0.borrow().value
&& self.0.borrow().children == other.0.borrow().children
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -184,4 +205,31 @@ mod tests {
assert!(tree2.find_bfs(|val| *val == "16").is_some()); assert!(tree2.find_bfs(|val| *val == "16").is_some());
assert!(tree2.find_bfs(|val| *val == "17").is_some()); assert!(tree2.find_bfs(|val| *val == "17").is_some());
} }
#[test]
fn path_to_on_empty_tree_returns_empty() {
let tree: Tree<&str> = Tree::default();
assert_eq!(tree.path_to(|val| *val == "i"), vec![]);
}
// A
// B G H
// C I
// D E F
#[test]
fn it_can_find_a_path_to_a_node() {
let (tree, a) = Tree::new("A");
let b = a.add_child_value("B");
let c = b.add_child_value("C");
let _d = c.add_child_value("D");
let _e = c.add_child_value("D");
let _f = c.add_child_value("D");
let _g = a.add_child_value("G");
let h = a.add_child_value("H");
let i = a.add_child_value("I");
assert_eq!(tree.path_to(|val| *val == "z"), vec![]);
assert_eq!(tree.path_to(|val| *val == "i"), vec![a, h, i]);
}
} }