1
2pub mod signed;
3
4use std::cmp;
5
6const RADIX: usize = 4;
8
9#[derive(Debug, Clone)]
10pub struct Node {
11 idx: u32,
12 parent: Option<u32>,
13 children: [Option<u32>; RADIX],
14 leaves: (u32, u32),
16 nb_tree_leaves: u32,
17 level: u32,
18}
19
20impl Node {
21 fn new_leaf(idx: usize, nb_tree_leaves: usize) -> Node {
22 let idx = idx as u32;
23 Node {
24 idx,
25 parent: None,
26 children: [None; RADIX],
27 leaves: (idx, (idx+1) % nb_tree_leaves as u32),
28 nb_tree_leaves: nb_tree_leaves as u32,
29 level: 0,
30 }
31 }
32
33 pub fn idx(&self) -> usize {
34 self.idx as usize
35 }
36
37 pub fn internal_idx(&self) -> usize {
41 self.idx.checked_sub(self.nb_tree_leaves)
42 .expect("called internal_idx on leaf node") as usize
43 }
44
45 pub fn parent(&self) -> Option<usize> {
46 self.parent.map(|p| p as usize)
47 }
48
49 pub fn children(&self) -> impl Iterator<Item = usize> {
50 self.children.clone().into_iter().filter_map(|c| c).map(|c| c as usize)
51 }
52
53 pub fn level(&self) -> usize {
55 self.level as usize
56 }
57
58 pub fn internal_level(&self) -> usize {
64 self.level.checked_sub(1).expect("called internal_level on leaf node") as usize
65 }
66
67 pub fn leaves(&self) -> impl Iterator<Item = usize> + Clone {
69 let (first, last) = self.leaves;
70 let nb = self.nb_tree_leaves;
71 (first..)
72 .take(nb as usize)
73 .map(move |e| e % nb)
74 .take_while(move |e| first == last || *e != last)
75 .map(|e| e as usize)
76 }
77
78 pub fn is_leaf(&self) -> bool {
79 self.children.iter().all(|o| o.is_none())
80 }
81
82 pub fn is_root(&self) -> bool {
83 self.parent.is_none()
84 }
85}
86
87#[derive(Debug, Clone)]
91pub struct Tree {
92 nodes: Vec<Node>,
95 nb_leaves: usize,
96}
97
98impl Tree {
99 pub fn nb_nodes_for_leaves(nb_leaves: usize) -> usize {
102 let mut ret = nb_leaves;
103 let mut left = nb_leaves;
104 while left > 1 {
105 let radix = cmp::min(left, RADIX);
106 left -= radix;
107 left += 1;
108 ret += 1;
109 }
110 ret
111 }
112
113 pub fn new(
114 nb_leaves: usize,
115 ) -> Tree {
116 assert_ne!(nb_leaves, 0, "trees can't be empty");
117
118 let mut nodes = Vec::with_capacity(Tree::nb_nodes_for_leaves(nb_leaves));
119
120 nodes.extend((0..nb_leaves).map(|i| Node::new_leaf(i, nb_leaves)));
122
123 let mut cursor = 0;
124 while cursor < nodes.len() - 1 {
127 let mut children = [None; RADIX];
128 let mut nb_children = 0;
129 let mut max_child_level = 0;
130 while cursor < nodes.len() && nb_children < RADIX {
131 children[nb_children] = Some(cursor as u32);
132
133 let new_idx = nodes.len(); let child = &mut nodes[cursor];
135 child.parent = Some(new_idx as u32);
136
137 if child.level > max_child_level {
139 max_child_level = child.level;
140 }
141
142 cursor += 1;
143 nb_children += 1;
144 }
145 nodes.push(Node {
146 idx: nodes.len() as u32,
147 leaves: (
148 nodes[children.first().unwrap().unwrap() as usize].leaves.0,
149 nodes[children.iter().filter_map(|c| *c).last().unwrap() as usize].leaves.1,
150 ),
151 children,
152 level: max_child_level + 1,
153 parent: None,
154 nb_tree_leaves: nb_leaves as u32,
155 });
156 }
157
158 Tree { nodes, nb_leaves }
159 }
160
161 pub fn nb_leaves(&self) -> usize {
162 self.nb_leaves
163 }
164
165 pub fn nb_nodes(&self) -> usize {
166 self.nodes.len()
167 }
168
169 pub fn nb_internal_nodes(&self) -> usize {
171 self.nodes.len().checked_sub(self.nb_leaves)
172 .expect("tree can't have less nodes than leaves")
173 }
174
175 pub fn node_at(&self, node_idx: usize) -> &Node {
176 self.nodes.get(node_idx).expect("node_idx out of bounds")
177 }
178
179 pub fn root(&self) -> &Node {
180 self.nodes.last().expect("no empty trees")
181 }
182
183 pub fn iter(&self) -> std::slice::Iter<'_, Node> {
185 self.nodes.iter()
186 }
187
188 pub fn iter_internal(&self) -> std::slice::Iter<'_, Node> {
191 self.nodes[self.nb_leaves..].iter()
192 }
193
194 pub fn into_iter(self) -> std::vec::IntoIter<Node> {
196 self.nodes.into_iter()
197 }
198
199 pub fn iter_branch(&self, leaf_idx: usize) -> BranchIter<'_> {
202 assert!(leaf_idx < self.nodes.len());
203 BranchIter {
204 tree: &self,
205 cursor: Some(leaf_idx),
206 }
207 }
208
209 pub fn parent_idx_of(&self, idx: usize) -> Option<usize> {
210 self.nodes.get(idx).and_then(|n| n.parent.map(|c| c as usize))
211 }
212
213 pub fn parent_idx_of_with_sibling_idx(&self, idx: usize) -> Option<(usize, usize)> {
216 self.nodes.get(idx).and_then(|n| n.parent).map(|parent_idx| {
217 let child_idx = self.nodes[parent_idx as usize].children.iter()
218 .position(|c| *c == Some(idx as u32))
219 .expect("broken tree");
220 (self.nodes[parent_idx as usize].idx as usize, child_idx as usize)
221 })
222 }
223
224}
225
226#[derive(Clone)]
228pub struct BranchIter<'a> {
229 tree: &'a Tree,
230 cursor: Option<usize>,
231}
232
233impl<'a> Iterator for BranchIter<'a> {
234 type Item = &'a Node;
235 fn next(&mut self) -> Option<Self::Item> {
236 if let Some(cursor) = self.cursor {
237 let ret = &self.tree.nodes[cursor];
238 self.cursor = ret.parent();
239 Some(ret)
240 } else {
241 None
242 }
243 }
244}
245
246#[cfg(test)]
247mod test {
248 use std::collections::HashSet;
249
250use super::*;
251
252 #[test]
253 fn test_simple_tree() {
254 for n in 1..100 {
255 let tree = Tree::new(n);
256
257 assert!(tree.nodes.iter().rev().skip(1).all(|n| n.parent.is_some()));
258 assert!(tree.nodes.iter().enumerate().skip(tree.nb_leaves).all(|(i, n)| {
259 n.children.iter().filter_map(|v| *v)
260 .all(|c| tree.nodes[c as usize].parent == Some(i as u32))
261 }));
262 assert!(tree.nodes.iter().enumerate().rev().skip(1).all(|(i, n)| {
263 let parent_idx = n.parent.unwrap() as usize;
264 tree.nodes[parent_idx].children.iter().find(|c| **c == Some(i as u32)).is_some()
265 }));
266 assert_eq!(Tree::nb_nodes_for_leaves(n), tree.nb_nodes(), "leaves: {}", n);
267 }
268 }
269
270 #[test]
271 fn test_leaves_range() {
272 for n in 1..42 {
273 let tree = Tree::new(n);
274
275 for node in &tree.nodes[0..tree.nb_leaves()] {
276 assert_eq!(node.leaves().collect::<Vec<_>>(), vec![node.idx()]);
277 }
278 for node in tree.iter() {
279 if !node.is_leaf() {
280 assert_eq!(
281 node.leaves().count(),
282 node.children().map(|c| tree.nodes[c].leaves().count()).sum::<usize>(),
283 "idx: {}", node.idx(),
284 );
285 }
286 assert!(node.leaves().all(|l| l < tree.nb_leaves()));
287 assert_eq!(
288 node.leaves().count(),
289 node.leaves().collect::<HashSet<_>>().len(),
290 );
291 }
292 println!("n={n} ok");
293 }
294 }
295}