use super::ST;
struct Node<K, V> {
key: K,
value: V,
next: Link<K, V>,
}
type Link<K, V> = Option<Box<Node<K, V>>>;
#[derive(Default)]
pub struct SequentialSearchST<K: PartialOrd, V> {
first: Link<K, V>,
}
pub struct IterMut<K, V> {
first: Link<K, V>,
}
impl<K: PartialOrd, V> SequentialSearchST<K, V> {
pub fn iter_mut(&mut self) -> IterMut<K, V> {
IterMut {
first: self.first.take(),
}
}
}
impl<K: PartialOrd, V> Iterator for IterMut<K, V> {
type Item = (K, V);
fn next(&mut self) -> Option<Self::Item> {
let ans = self.first.take();
ans.map(|mut f| {
self.first = f.next.take();
(f.key, f.value)
})
}
}
impl<K: PartialOrd, V> ST<K, V> for SequentialSearchST<K, V> {
fn put(&mut self, key: K, value: V) {
let first = self.first.as_deref_mut();
match first {
None => {
self.first = Some(Box::new(Node {
key,
value,
next: self.first.take(),
}));
}
Some(first) => {
if first.key > key {
self.first = Some(Box::new(Node {
key,
value,
next: self.first.take(),
}));
} else if first.key == key {
first.value = value;
} else {
let mut p = first;
let mut current = p.next.as_deref_mut();
if current.is_none() {
p.next = Some(Box::new(Node {
key,
value,
next: None,
}));
return;
}
while let Some(node) = current {
if key == node.key {
node.value = value;
break;
} else if key < node.key {
p.next = Some(Box::new(Node {
key,
value,
next: p.next.take(),
}));
break;
} else {
let next = node.next.as_deref();
if next.is_none() {
node.next = Some(Box::new(Node {
key,
value,
next: None,
}));
break;
} else {
current = node.next.as_deref_mut();
}
}
}
}
}
}
}
fn get(&self, key: &K) -> Option<&V> {
let mut current = self.first.as_deref();
while let Some(node) = current {
if &node.key == key {
return Some(&node.value);
} else {
current = node.next.as_deref();
}
}
None
}
fn delete(&mut self, key: &K) {
let first = self.first.as_deref_mut();
if first.is_none() {
return;
}
let first = first.unwrap();
if &first.key == key {
self.first = first.next.take();
return;
}
let mut p = first;
let a = unsafe { (p as *mut Node<K, V>).as_mut() };
let mut current = a.unwrap().next.as_deref_mut();
while let Some(node) = current {
if &node.key == key {
p.next = node.next.take();
break;
} else {
p = node;
let a = unsafe { (p as *mut Node<K, V>).as_mut() };
current = a.unwrap().next.as_deref_mut();
}
}
}
fn contains(&self, key: &K) -> bool {
self.get(key).is_some()
}
fn is_empty(&self) -> bool {
self.first.is_none()
}
fn size(&self) -> usize {
let mut current = self.first.as_deref();
let mut size = 0;
while let Some(node) = current {
size += 1;
current = node.next.as_deref();
}
size
}
fn min(&self) -> Option<&K> {
let mut current = self.first.as_deref();
let mut result = None;
while let Some(node) = current {
if let Some(key) = result {
if key > &node.key {
result = Some(&node.key)
}
} else {
result = Some(&node.key);
}
current = node.next.as_deref();
}
result
}
fn max(&self) -> Option<&K> {
let mut current = self.first.as_deref();
let mut result = None;
while let Some(node) = current {
if let Some(key) = result {
if key < &node.key {
result = Some(&node.key)
}
} else {
result = Some(&node.key);
}
current = node.next.as_deref();
}
result
}
fn floor(&self, key: &K) -> Option<&K> {
let mut current = self.first.as_deref();
let mut result = None;
while let Some(node) = current {
let current_key = &node.key;
if let Some(inner) = result {
if key >= current_key && inner < current_key {
result = Some(current_key)
}
} else if key >= current_key {
result = Some(current_key);
}
current = node.next.as_deref();
}
result
}
fn ceiling(&self, key: &K) -> Option<&K> {
let mut current = self.first.as_deref();
let mut result = None;
while let Some(node) = current {
let current_key = &node.key;
if let Some(inner) = result {
if key <= current_key && inner > current_key {
result = Some(current_key)
}
} else if key <= current_key {
result = Some(current_key);
}
current = node.next.as_deref();
}
result
}
fn rank(&self, key: &K) -> usize {
let mut current = self.first.as_deref();
let mut size = 0;
while let Some(node) = current {
if &node.key < key {
size += 1;
}
current = node.next.as_deref();
}
size
}
fn select(&self, k: usize) -> Option<&K> {
let mut current = self.first.as_deref();
let mut result = None;
let mut i: usize = 0;
while let Some(node) = current {
if i == k {
result = Some(&node.key);
break;
}
current = node.next.as_deref();
i += 1;
}
result
}
}
#[cfg(test)]
mod test {
use crate::search::ST;
use super::SequentialSearchST;
#[test]
fn test() {
let mut st = SequentialSearchST::default();
assert!(st.is_empty());
assert_eq!(st.size(), 0);
st.put(1, "a");
st.put(2, "b");
st.put(3, "c");
assert_eq!(st.size(), 3);
assert_eq!(st.max(), Some(&3));
assert_eq!(st.min(), Some(&1));
assert_eq!(st.get(&1), Some(&"a"));
assert_eq!(st.get(&2), Some(&"b"));
assert_eq!(st.get(&3), Some(&"c"));
assert_eq!(st.select(0), Some(&1));
assert_eq!(st.select(2), Some(&3));
assert_eq!(st.select(3), None);
assert_eq!(st.floor(&2), Some(&2));
assert_eq!(st.floor(&0), None);
assert_eq!(st.ceiling(&2), Some(&2));
assert_eq!(st.ceiling(&4), None);
st.delete(&2);
assert_eq!(st.get(&2), None);
assert_eq!(st.ceiling(&2), Some(&3));
assert_eq!(st.floor(&2), Some(&1));
st.delete_min();
assert_eq!(st.min(), Some(&3));
st.put(2, "bb");
st.delete_max();
assert_eq!(st.max(), Some(&2));
st.delete_max();
st.delete_min();
assert!(st.is_empty());
}
}