catlog/one/
tree_algorithms.rs1use ego_tree::iter::{Descendants, Edge};
4use ego_tree::{NodeId, NodeRef, Tree};
5use itertools::{EitherOrBoth::Both, Itertools};
6use std::collections::VecDeque;
7
8pub trait TreeTraversal<T> {
10 fn dfs(&self) -> Descendants<'_, T>;
12
13 fn bfs(&self) -> BreadthFirstTraversal<'_, T>;
15
16 fn left_boundary(&self) -> impl Iterator<Item = Self>;
18
19 fn right_boundary(&self) -> impl Iterator<Item = Self>;
21}
22
23pub struct BreadthFirstTraversal<'a, T: 'a> {
25 tree: &'a Tree<T>,
26 queue: VecDeque<(NodeId, usize)>,
27 current_level: usize,
28}
29
30impl<'a, T: 'a> BreadthFirstTraversal<'a, T> {
31 pub fn starting_at(root: NodeRef<'a, T>) -> Self {
33 let tree = root.tree();
34 let mut queue = VecDeque::new();
35 queue.push_back((root.id(), 1));
36 Self { tree, queue, current_level: 0 }
37 }
38
39 pub fn peek_at_same_level(&self) -> Option<NodeRef<'a, T>> {
41 self.queue.front().and_then(|(id, level)| {
42 if *level == self.current_level {
43 self.tree.get(*id)
44 } else {
45 None
46 }
47 })
48 }
49}
50
51impl<'a, T: 'a> Iterator for BreadthFirstTraversal<'a, T> {
52 type Item = NodeRef<'a, T>;
53
54 fn next(&mut self) -> Option<Self::Item> {
55 let (id, level) = self.queue.pop_front()?;
56 self.current_level = level;
57 let node = self.tree.get(id).unwrap();
58 for child in node.children() {
59 self.queue.push_back((child.id(), level + 1));
60 }
61 Some(node)
62 }
63}
64
65impl<'a, T: 'a> std::iter::FusedIterator for BreadthFirstTraversal<'a, T> {}
66
67impl<'a, T: 'a> TreeTraversal<T> for NodeRef<'a, T> {
68 fn dfs(&self) -> Descendants<'a, T> {
71 self.descendants()
72 }
73
74 fn bfs(&self) -> BreadthFirstTraversal<'a, T> {
76 BreadthFirstTraversal::starting_at(*self)
77 }
78
79 fn left_boundary(&self) -> impl Iterator<Item = Self> {
80 let mut maybe_node = Some(*self);
81 std::iter::from_fn(move || {
82 let prev = maybe_node;
83 maybe_node = maybe_node.and_then(|node| node.first_child());
84 prev
85 })
86 }
87
88 fn right_boundary(&self) -> impl Iterator<Item = Self> {
89 let mut maybe_node = Some(*self);
90 std::iter::from_fn(move || {
91 let prev = maybe_node;
92 maybe_node = maybe_node.and_then(|node| node.last_child());
93 prev
94 })
95 }
96}
97
98pub trait TreeIsomorphism<T> {
100 fn is_isomorphic_to(&self, other: &Self) -> bool;
110}
111
112impl<T> TreeIsomorphism<T> for Tree<T>
113where
114 T: Eq,
115{
116 fn is_isomorphic_to(&self, other: &Self) -> bool {
117 self.root()
118 .traverse()
119 .zip_longest(other.root().traverse())
120 .all(|pair| match pair {
121 Both(Edge::Open(n1), Edge::Open(n2)) | Both(Edge::Close(n1), Edge::Close(n2)) => {
122 n1.value() == n2.value()
123 }
124 _ => false,
125 })
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132 use ego_tree::tree;
133
134 #[test]
135 fn dfs() {
136 let tree = tree!('a' => { 'b' => { 'd', 'e' }, 'c' });
137 let values: Vec<_> = tree.root().dfs().map(|node| *node.value()).collect();
138 assert_eq!(values, vec!['a', 'b', 'd', 'e', 'c']);
139 }
140
141 #[test]
142 fn bfs() {
143 let tree = tree!('a' => { 'b' => { 'd', 'e' }, 'c' });
144 let values: Vec<_> = tree.root().bfs().map(|node| *node.value()).collect();
145 assert_eq!(values, vec!['a', 'b', 'c', 'd', 'e']);
146
147 let tree = tree!('a' => { 'b' => {'d'}, 'c' => {'e'} });
148 let root = tree.root();
149 let mut traverse = root.bfs();
150 traverse.next();
151 assert!(traverse.peek_at_same_level().is_none());
152 assert_eq!(traverse.nth(2).map(|node| *node.value()), Some('d'));
153 assert_eq!(traverse.peek_at_same_level().map(|node| *node.value()), Some('e'));
154 }
155
156 #[test]
157 fn isomorphism() {
158 let tree = tree!('a' => { 'b' => { 'd', 'e' }, 'c' });
159 assert!(tree.is_isomorphic_to(&tree));
160
161 let other = tree!('a' => { 'b' => { 'd' }, 'e' => { 'c' }});
162 let tree_dfs_values: Vec<_> = tree.root().dfs().map(|node| *node.value()).collect();
163 let other_dfs_values: Vec<_> = other.root().dfs().map(|node| *node.value()).collect();
164 assert_eq!(tree_dfs_values, other_dfs_values);
165 assert!(!tree.is_isomorphic_to(&other));
166 }
167}