Skip to content

Commit 0adcf46

Browse files
committed
add delete method to Trie
1 parent dbb20e9 commit 0adcf46

File tree

1 file changed

+102
-0
lines changed

1 file changed

+102
-0
lines changed

src/data_structures/trie.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,60 @@ where
7676
}
7777
node.value.as_ref()
7878
}
79+
80+
/// Removes a value from the Trie associated with a sequence of keys.
81+
///
82+
/// # Arguments
83+
/// - `key`: An iterable sequence of keys (e.g., characters in a string or integers in a vector).
84+
///
85+
/// # Returns
86+
/// An `Option` containing the removed value if the sequence of keys existed in the Trie,
87+
/// or `None` if it did not exist.
88+
pub fn delete(&mut self, key: impl IntoIterator<Item = Key>) -> Option<Type>
89+
where
90+
Key: Eq + Hash + Clone,
91+
{
92+
let key_vec: Vec<Key> = key.into_iter().collect();
93+
if key_vec.is_empty() {
94+
return self.root.value.take();
95+
}
96+
97+
Self::delete_recursive(&mut self.root, &key_vec, 0)
98+
}
99+
100+
/// Recursive helper function for deletion.
101+
///
102+
/// # Arguments
103+
/// - `node`: The current node being processed.
104+
/// - `key`: The complete key sequence as a vector.
105+
/// - `index`: The current position in the key sequence.
106+
///
107+
/// # Returns
108+
/// An `Option` containing the removed value if found, or `None` if not found.
109+
fn delete_recursive(node: &mut Node<Key, Type>, key: &[Key], index: usize) -> Option<Type>
110+
where
111+
Key: Eq + Hash,
112+
{
113+
if index == key.len() {
114+
// We've reached the end of the key sequence
115+
return node.value.take();
116+
}
117+
118+
let current_key = &key[index];
119+
if let Some(child_node) = node.children.get_mut(current_key) {
120+
let removed_value = Self::delete_recursive(child_node, key, index + 1);
121+
122+
// Remove child node if it has no value and no children
123+
if child_node.value.is_none() && child_node.children.is_empty() {
124+
node.children.remove(current_key);
125+
}
126+
127+
removed_value
128+
} else {
129+
// Key not found
130+
None
131+
}
132+
}
79133
}
80134

81135
#[cfg(test)]
@@ -152,4 +206,52 @@ mod tests {
152206
assert_eq!(trie.get("apple".chars()), Some(&10));
153207
assert_eq!(trie.get("applepie".chars()), None);
154208
}
209+
210+
#[test]
211+
fn test_delete_basic() {
212+
let mut trie = Trie::new();
213+
trie.insert("foo".chars(), 42);
214+
trie.insert("bar".chars(), 100);
215+
216+
assert_eq!(trie.delete("foo".chars()), Some(42));
217+
assert_eq!(trie.get("foo".chars()), None);
218+
assert_eq!(trie.get("bar".chars()), Some(&100));
219+
assert_eq!(trie.delete("nonexistent".chars()), None);
220+
}
221+
222+
#[test]
223+
fn test_delete_overlapping_keys() {
224+
let mut trie = Trie::new();
225+
trie.insert("car".chars(), 1);
226+
trie.insert("cart".chars(), 2);
227+
trie.insert("carter".chars(), 3);
228+
229+
assert_eq!(trie.delete("cart".chars()), Some(2));
230+
assert_eq!(trie.get("car".chars()), Some(&1));
231+
assert_eq!(trie.get("cart".chars()), None);
232+
assert_eq!(trie.get("carter".chars()), Some(&3));
233+
}
234+
235+
#[test]
236+
fn test_delete_empty_key_and_cleanup() {
237+
let mut trie: Trie<char, i32> = Trie::new();
238+
trie.insert("".chars(), 42);
239+
trie.insert("hello".chars(), 1);
240+
241+
assert_eq!(trie.delete("".chars()), Some(42));
242+
assert_eq!(trie.get("".chars()), None);
243+
assert_eq!(trie.delete("hello".chars()), Some(1));
244+
assert_eq!(trie.delete("".chars()), None);
245+
}
246+
247+
#[test]
248+
fn test_delete_with_integers() {
249+
let mut trie = Trie::new();
250+
trie.insert(vec![1, 2, 3], "first");
251+
trie.insert(vec![1, 2, 3, 4], "second");
252+
253+
assert_eq!(trie.delete(vec![1, 2, 3]), Some("first"));
254+
assert_eq!(trie.get(vec![1, 2, 3]), None);
255+
assert_eq!(trie.get(vec![1, 2, 3, 4]), Some(&"second"));
256+
}
155257
}

0 commit comments

Comments
 (0)