cartesian_tree/tree/
traits.rs1pub trait HasParent {
3 type Node: Clone;
4
5 fn parent(&self) -> Option<Self::Node>;
7}
8
9pub trait NodeEquality {
11 fn is_same(&self, other: &Self) -> bool;
13}
14
15pub trait HasChildren {
17 type Node: Clone;
18
19 fn children(&self) -> Vec<Self::Node>;
21}
22
23pub trait Walking: HasParent<Node = Self> + NodeEquality + Clone {
25 fn depth(&self) -> usize {
31 let mut depth = 0;
32 let mut current = self.clone();
33 while let Some(parent) = current.parent() {
34 depth += 1;
35 current = parent;
36 }
37 depth
38 }
39
40 fn walk_up(&self, steps: usize) -> Option<Self> {
50 let mut current = self.clone();
51 for _ in 0..steps {
52 current = current.parent()?;
53 }
54 Some(current)
55 }
56
57 #[must_use]
63 fn root(&self) -> Self {
64 self.walk_up(self.depth()).unwrap_or_else(|| self.clone())
65 }
66
67 fn lca_with(&self, other: &Self) -> Option<Self> {
77 let mut own = self.clone();
78 let mut other = other.clone();
79
80 let own_depth = self.depth();
81 let other_depth = other.depth();
82
83 if own_depth > other_depth {
85 own = own.walk_up(own_depth - other_depth)?;
86 } else if other_depth > own_depth {
87 other = other.walk_up(other_depth - own_depth)?;
88 }
89
90 while !own.is_same(&other) {
92 own = own.parent()?;
93 other = other.parent()?;
94 }
95 Some(own)
96 }
97}
98
99impl<T> Walking for T where T: HasParent<Node = T> + NodeEquality + Clone {}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104 use crate::frame::Frame;
105 use nalgebra::{UnitQuaternion, Vector3};
106
107 #[test]
108 fn test_depth() {
109 let root = Frame::new_origin("root");
110 assert_eq!(root.depth(), 0);
111
112 let child = root
113 .add_child("child", Vector3::zeros(), UnitQuaternion::identity())
114 .unwrap();
115 assert_eq!(child.depth(), 1);
116
117 let grandchild = child
118 .add_child("grandchild", Vector3::zeros(), UnitQuaternion::identity())
119 .unwrap();
120 assert_eq!(grandchild.depth(), 2);
121 }
122
123 #[test]
124 fn test_walk_up() {
125 let root = Frame::new_origin("root");
126 let child = root
127 .add_child("child", Vector3::zeros(), UnitQuaternion::identity())
128 .unwrap();
129 let grandchild = child
130 .add_child("grandchild", Vector3::zeros(), UnitQuaternion::identity())
131 .unwrap();
132
133 assert!(grandchild.walk_up(0).unwrap().is_same(&grandchild));
134 assert!(grandchild.walk_up(1).unwrap().is_same(&child));
135 assert!(grandchild.walk_up(2).unwrap().is_same(&root));
136 assert!(grandchild.walk_up(3).is_none());
137 }
138
139 #[test]
140 fn test_root() {
141 let root = Frame::new_origin("root");
142 let child = root
143 .add_child("child", Vector3::zeros(), UnitQuaternion::identity())
144 .unwrap();
145 let grandchild = child
146 .add_child("grandchild", Vector3::zeros(), UnitQuaternion::identity())
147 .unwrap();
148
149 assert!(root.root().is_same(&root));
150 assert!(child.root().is_same(&root));
151 assert!(grandchild.root().is_same(&root));
152 }
153
154 #[test]
155 fn test_lca_with() {
156 let root = Frame::new_origin("root");
157 let child1 = root
158 .add_child("child1", Vector3::zeros(), UnitQuaternion::identity())
159 .unwrap();
160 let child2 = root
161 .add_child("child2", Vector3::zeros(), UnitQuaternion::identity())
162 .unwrap();
163 let grandchild1 = child1
164 .add_child("grandchild1", Vector3::zeros(), UnitQuaternion::identity())
165 .unwrap();
166 let grandchild2 = child2
167 .add_child("grandchild2", Vector3::zeros(), UnitQuaternion::identity())
168 .unwrap();
169
170 assert!(child1.lca_with(&child1).unwrap().is_same(&child1));
172 assert!(child1.lca_with(&child2).unwrap().is_same(&root));
174 assert!(grandchild1.lca_with(&child1).unwrap().is_same(&child1));
176 assert!(grandchild1.lca_with(&grandchild2).unwrap().is_same(&root));
178 }
179}