algae_trees/data/btree/
btree.rs1use std::convert::TryFrom;
8
9struct Node<T> {
10 keys: Vec<T>,
11 children: Vec<Node<T>>,
12}
13
14impl<T> Node<T>
15where
16 T: Ord,
17{
18 fn new(degree: usize, _keys: Option<Vec<T>>, _children: Option<Vec<Node<T>>>) -> Self {
19 Node {
20 keys: match _keys {
21 Some(_keys) => _keys,
22 None => Vec::with_capacity(degree - 1),
23 },
24 children: match _children {
25 Some(_children) => _children,
26 None => Vec::with_capacity(degree),
27 },
28 }
29 }
30
31 fn is_leaf(&self) -> bool {
32 self.children.is_empty()
33 }
34}
35
36pub struct BTree<T> {
37 root: Node<T>,
38 props: BTreeProps,
39}
40
41impl<T> BTree<T>
42 where
43 T: Ord + Copy + std::fmt::Debug + Default,
44{
45 pub fn new(branch_factor: usize) -> Self {
46 let degree = 2 * branch_factor;
47 Self {
48 root: Node::new(degree, None, None),
49 props: BTreeProps::new(degree),
50 }
51 }
52
53 pub fn insert(&mut self, key: T) {
54 if self.props.is_maxed_out(&self.root) {
55 let mut new_root = Node::new(self.props.degree, None, None);
56 std::mem::swap(&mut new_root, &mut self.root);
57 self.root.children.insert(0, new_root);
58 self.props.split_child(&mut self.root, 0);
59 }
60
61 self.props.insert_non_full(&mut self.root, key);
62 }
63
64 pub fn transverse(&self) {
65 self.props.transverse_node(&self.root, 0);
66 println!();
67 }
68
69 pub fn search(&self, key: T) -> bool {
70 let mut current_node = &self.root;
71 let mut index: isize;
72 loop {
73 index = isize::try_from(current_node.keys.len()).ok().unwrap() - 1;
74 while index >= 0 && current_node.keys[index as usize] > key {
75 index -= 1;
76 }
77
78 let u_index: usize = usize::try_from(index + 1).ok().unwrap();
79 if index >= 0 && current_node.keys[u_index - 1] == key {
80 break true;
81 } else if current_node.is_leaf() {
82 break false;
83 } else {
84 current_node = ¤t_node.children[u_index];
85 }
86 }
87 }
88}
89
90struct BTreeProps {
91 degree: usize,
92 max_keys: usize,
93 mid_key_index: usize,
94}
95
96impl BTreeProps {
97 fn new(degree: usize) -> Self {
98 Self {
99 degree,
100 max_keys: degree - 1,
101 mid_key_index: (degree - 1) / 2,
102 }
103 }
104
105 fn is_maxed_out<T: Ord + Copy>(&self, node: &Node<T>) -> bool {
106 node.keys.len() == self.max_keys
107 }
108
109 fn split_child<T: Ord + Copy + Default>(&self, parent: &mut Node<T>, child_index: usize) {
110 let child = &mut parent.children[child_index];
111 let middle_key = child.keys[self.mid_key_index];
112 let right_keys = match child.keys.split_off(self.mid_key_index).split_first() {
113 Some((_first, _others)) => _others.to_vec(),
114 None => Vec::with_capacity(self.max_keys),
115 };
116 let right_children = if !child.is_leaf() {
117 Some(child.children.split_off(self.mid_key_index + 1))
118 } else {
119 None
120 };
121 let new_child_node: Node<T> = Node::new(self.degree, Some(right_keys), right_children);
122
123 parent.keys.insert(child_index, middle_key);
124 parent.children.insert(child_index + 1, new_child_node);
125 }
126
127 fn insert_non_full<T: Ord + Copy + Default>(&mut self, node: &mut Node<T>, key: T) {
128 let mut index: isize = isize::try_from(node.keys.len()).ok().unwrap() - 1;
129 while index >= 0 && node.keys[index as usize] >= key {
130 index -= 1;
131 }
132
133 let mut u_index: usize = usize::try_from(index + 1).ok().unwrap();
134 if node.is_leaf() {
135 node.keys.insert(u_index, key);
136 } else {
137 if self.is_maxed_out(&node.children[u_index]) {
138 self.split_child(node, u_index);
139 if node.keys[u_index] < key {
140 u_index += 1;
141 }
142 }
143
144 self.insert_non_full(&mut node.children[u_index], key);
145 }
146 }
147
148 fn transverse_node<T: Ord + std::fmt::Debug>(&self, node: &Node<T>, depth: usize) {
149 if node.is_leaf() {
150 print!(" {0:{<1$}{2:?}{0:}<1$} ", "", depth, node.keys);
151 } else {
152 let _depth = depth + 1;
153 for (index, key) in node.keys.iter().enumerate() {
154 self.transverse_node(&node.children[index], _depth);
155 print!("{0:{<1$}{2:?}{0:}<1$}", "", depth, key);
156 }
157
158 self.transverse_node(node.children.last().unwrap(), _depth);
159 }
160 }
161}
162
163#[cfg(test)]
164mod tests {
165 use super::BTree;
166
167 #[test]
168 fn test_search() {
169 let values = [10, 20, 30, 5, 6, 7, 11, 12, 15];
170 let mut tree = BTree::new(2);
171 for i in 0..values.len() {
172 tree.insert(values[i])
173 }
174 assert!(tree.search(15));
175 assert_eq!(tree.search(16), false);
176 }
177}