Start writing functions for finding a node within the tree
This commit is contained in:
parent
0aecaee760
commit
511f1080a7
|
@ -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]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue