use std::ops::Index;
use std::collections::LinkedList;
use super::ST;
pub struct LinkedST<K, V> {
t: LinkedList<(K,V)>
}
impl<K: Eq, V> ST<K,V> for LinkedST<K, V> {
fn new() -> Self {
LinkedST {
t: LinkedList::new()
}
}
fn put(&mut self, key: K, val: V) {
for &mut (ref mut k, ref mut v) in self.t.iter_mut() {
if k == &key {
*v = val;
return;
}
}
self.t.push_front((key,val))
}
fn get(&self, key: &K) -> Option<&V> {
for &(ref k, ref v) in self.t.iter() {
if k == key {
return Some(v)
}
}
None
}
fn delete(&mut self, key: &K) {
let mut i = 0;
let mut found = false;
for &(ref k, _) in self.t.iter() {
if k == key {
found = true;
break
} else {
i += 1;
}
}
if found {
let mut remains = self.t.split_off(i);
self.t.pop_back();
self.t.append(&mut remains)
}
}
fn is_empty(&self) -> bool {
self.t.len() == 0
}
fn size(&self) -> usize {
self.t.len()
}
}
impl<K: Eq, V> Index<K> for LinkedST<K, V> {
type Output = V;
fn index<'a>(&'a self, index: K) -> &'a Self::Output {
self.get(&index).unwrap()
}
}
#[test]
fn test_linked_symbol_table() {
let mut st: LinkedST<char,usize> = ST::new();
assert!(st.is_empty());
for (i, c) in "SEARCHEXAMPLE".chars().enumerate() {
st.put(c, i);
}
assert_eq!(st.get(&'X'), Some(&7));
assert_eq!(st.get(&'E'), Some(&12));
assert_eq!(st['E'], 12);
assert_eq!(st.size(), 10);
assert_eq!(st.is_empty(), false);
}