use rand::Rng;
use std::cmp::Ordering;
struct Node<T> {
key: T,
priority: u32,
left: Option<Box<Node<T>>>,
right: Option<Box<Node<T>>>,
}
impl<T> Node<T> {
fn new(key: T, priority: u32) -> Self {
Node {
key,
priority,
left: None,
right: None,
}
}
}
pub struct Treap<T> {
root: Option<Box<Node<T>>>,
size: usize,
}
impl<T: Ord> Treap<T> {
pub fn new() -> Self {
Treap {
root: None,
size: 0,
}
}
pub fn len(&self) -> usize {
self.size
}
#[allow(dead_code)]
pub fn is_empty(&self) -> bool {
self.size == 0
}
pub fn insert<R: Rng>(&mut self, key: T, rng: &mut R) -> bool {
let priority = rng.random();
let (new_root, inserted) = Self::insert_node(self.root.take(), key, priority);
self.root = new_root;
if inserted {
self.size += 1;
}
inserted
}
pub fn contains(&self, key: &T) -> bool {
Self::contains_node(&self.root, key)
}
pub fn remove(&mut self, key: &T) -> bool {
let (new_root, removed) = Self::remove_node(self.root.take(), key);
self.root = new_root;
if removed {
self.size -= 1;
}
removed
}
#[allow(dead_code)]
pub fn clear(&mut self) {
self.root = None;
self.size = 0;
}
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&T) -> bool,
{
let (new_root, new_size) = Self::retain_node(self.root.take(), &mut f);
self.root = new_root;
self.size = new_size;
}
fn insert_node(
node: Option<Box<Node<T>>>,
key: T,
priority: u32,
) -> (Option<Box<Node<T>>>, bool) {
match node {
None => (Some(Box::new(Node::new(key, priority))), true),
Some(mut n) => match key.cmp(&n.key) {
Ordering::Less => {
let (new_left, inserted) = Self::insert_node(n.left, key, priority);
n.left = new_left;
let result = if inserted && n.left.as_ref().unwrap().priority > n.priority {
Self::rotate_right(n)
} else {
Some(n)
};
(result, inserted)
}
Ordering::Greater => {
let (new_right, inserted) = Self::insert_node(n.right, key, priority);
n.right = new_right;
let result = if inserted && n.right.as_ref().unwrap().priority > n.priority {
Self::rotate_left(n)
} else {
Some(n)
};
(result, inserted)
}
Ordering::Equal => (Some(n), false), },
}
}
fn contains_node(node: &Option<Box<Node<T>>>, key: &T) -> bool {
match node {
None => false,
Some(n) => match key.cmp(&n.key) {
Ordering::Less => Self::contains_node(&n.left, key),
Ordering::Greater => Self::contains_node(&n.right, key),
Ordering::Equal => true,
},
}
}
fn remove_node(node: Option<Box<Node<T>>>, key: &T) -> (Option<Box<Node<T>>>, bool) {
match node {
None => (None, false),
Some(mut n) => match key.cmp(&n.key) {
Ordering::Less => {
let (new_left, removed) = Self::remove_node(n.left, key);
n.left = new_left;
(Some(n), removed)
}
Ordering::Greater => {
let (new_right, removed) = Self::remove_node(n.right, key);
n.right = new_right;
(Some(n), removed)
}
Ordering::Equal => {
(Self::merge(n.left, n.right), true)
}
},
}
}
fn merge(left: Option<Box<Node<T>>>, right: Option<Box<Node<T>>>) -> Option<Box<Node<T>>> {
match (left, right) {
(None, right) => right,
(left, None) => left,
(Some(l), Some(r)) => {
if l.priority > r.priority {
let mut l = l;
l.right = Self::merge(l.right, Some(r));
Some(l)
} else {
let mut r = r;
r.left = Self::merge(Some(l), r.left);
Some(r)
}
}
}
}
fn rotate_right(mut node: Box<Node<T>>) -> Option<Box<Node<T>>> {
let mut new_root = node.left.take().unwrap();
node.left = new_root.right.take();
new_root.right = Some(node);
Some(new_root)
}
fn rotate_left(mut node: Box<Node<T>>) -> Option<Box<Node<T>>> {
let mut new_root = node.right.take().unwrap();
node.right = new_root.left.take();
new_root.left = Some(node);
Some(new_root)
}
fn retain_node<F>(node: Option<Box<Node<T>>>, f: &mut F) -> (Option<Box<Node<T>>>, usize)
where
F: FnMut(&T) -> bool,
{
match node {
None => (None, 0),
Some(mut n) => {
let (new_left, left_size) = Self::retain_node(n.left, f);
let (new_right, right_size) = Self::retain_node(n.right, f);
if f(&n.key) {
n.left = new_left;
n.right = new_right;
(Some(n), left_size + right_size + 1)
} else {
let merged = Self::merge(new_left, new_right);
(merged, left_size + right_size)
}
}
}
}
}
impl<T: Ord> Default for Treap<T> {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use rand::SeedableRng;
use rand::rngs::StdRng;
fn collect_inorder<T: Ord + Clone>(node: &Option<Box<Node<T>>>) -> Vec<T> {
match node {
None => vec![],
Some(n) => {
let mut result = collect_inorder(&n.left);
result.push(n.key.clone());
result.extend(collect_inorder(&n.right));
result
}
}
}
fn verify_heap_property<T: Ord>(node: &Option<Box<Node<T>>>) -> bool {
match node {
None => true,
Some(n) => {
let left_ok = n.left.as_ref().is_none_or(|l| n.priority >= l.priority);
let right_ok = n.right.as_ref().is_none_or(|r| n.priority >= r.priority);
left_ok
&& right_ok
&& verify_heap_property(&n.left)
&& verify_heap_property(&n.right)
}
}
}
#[test]
fn test_insert_and_contains() {
let mut treap = Treap::new();
let mut rng = StdRng::seed_from_u64(42);
treap.insert(5, &mut rng);
treap.insert(3, &mut rng);
treap.insert(7, &mut rng);
assert!(treap.contains(&5));
assert!(treap.contains(&3));
assert!(treap.contains(&7));
assert!(!treap.contains(&1));
assert_eq!(treap.len(), 3);
}
#[test]
fn test_remove() {
let mut treap = Treap::new();
let mut rng = StdRng::seed_from_u64(42);
treap.insert(5, &mut rng);
treap.insert(3, &mut rng);
treap.insert(7, &mut rng);
assert!(treap.remove(&3));
assert!(!treap.contains(&3));
assert_eq!(treap.len(), 2);
assert!(!treap.remove(&3)); }
#[test]
fn test_retain() {
let mut treap = Treap::new();
let mut rng = StdRng::seed_from_u64(42);
for i in 0..10 {
treap.insert(i, &mut rng);
}
treap.retain(|&x| x % 2 == 0);
assert_eq!(treap.len(), 5);
for i in 0..10 {
if i % 2 == 0 {
assert!(treap.contains(&i));
} else {
assert!(!treap.contains(&i));
}
}
}
#[test]
fn test_duplicate_insertion() {
let mut treap = Treap::new();
let mut rng = StdRng::seed_from_u64(42);
assert!(treap.insert(5, &mut rng)); assert!(treap.insert(3, &mut rng));
assert!(treap.insert(7, &mut rng));
assert_eq!(treap.len(), 3);
assert!(!treap.insert(5, &mut rng));
assert!(!treap.insert(3, &mut rng));
assert!(!treap.insert(7, &mut rng));
assert_eq!(treap.len(), 3);
assert!(treap.contains(&5));
assert!(treap.contains(&3));
assert!(treap.contains(&7));
assert!(treap.remove(&5));
assert_eq!(treap.len(), 2);
assert!(treap.insert(5, &mut rng)); assert_eq!(treap.len(), 3);
}
#[test]
fn test_bst_property() {
let mut treap = Treap::new();
let mut rng = StdRng::seed_from_u64(123);
let elements = vec![50, 25, 75, 10, 30, 60, 90, 5, 15, 27, 35];
for elem in &elements {
treap.insert(*elem, &mut rng);
}
let inorder = collect_inorder(&treap.root);
let mut sorted = elements.clone();
sorted.sort();
assert_eq!(inorder, sorted);
treap.remove(&25);
treap.remove(&75);
let inorder_after = collect_inorder(&treap.root);
let expected: Vec<i32> = sorted.into_iter().filter(|&x| x != 25 && x != 75).collect();
assert_eq!(inorder_after, expected);
}
#[test]
fn test_heap_property() {
let mut treap = Treap::new();
let mut rng = StdRng::seed_from_u64(456);
for i in 0..100 {
treap.insert(i, &mut rng);
assert!(
verify_heap_property(&treap.root),
"Heap property violated after inserting {}",
i
);
}
for i in (0..100).step_by(3) {
treap.remove(&i);
assert!(
verify_heap_property(&treap.root),
"Heap property violated after removing {}",
i
);
}
treap.retain(|&x| x % 2 == 0);
assert!(
verify_heap_property(&treap.root),
"Heap property violated after retain"
);
}
#[test]
fn test_stress_insert_remove() {
let mut treap = Treap::new();
let mut rng = StdRng::seed_from_u64(789);
for i in 0..1000 {
treap.insert(i, &mut rng);
}
assert_eq!(treap.len(), 1000);
for i in 0..1000 {
assert!(treap.contains(&i), "Element {} should be present", i);
}
for i in (0..1000).step_by(2) {
assert!(treap.remove(&i), "Should remove {}", i);
}
assert_eq!(treap.len(), 500);
for i in 0..1000 {
if i % 2 == 0 {
assert!(!treap.contains(&i), "Element {} should be removed", i);
} else {
assert!(treap.contains(&i), "Element {} should remain", i);
}
}
for i in (0..1000).step_by(2) {
assert!(treap.insert(i, &mut rng), "Should insert {}", i);
}
assert_eq!(treap.len(), 1000);
let inorder = collect_inorder(&treap.root);
let expected: Vec<i32> = (0..1000).collect();
assert_eq!(inorder, expected);
assert!(verify_heap_property(&treap.root));
}
#[test]
fn test_empty_tree_operations() {
let mut treap: Treap<i32> = Treap::new();
let mut rng = StdRng::seed_from_u64(999);
assert!(treap.is_empty());
assert_eq!(treap.len(), 0);
assert!(!treap.contains(&42));
assert!(!treap.remove(&42));
treap.retain(|_| true);
assert!(treap.is_empty());
treap.clear();
assert!(treap.is_empty());
treap.insert(1, &mut rng);
treap.insert(2, &mut rng);
assert_eq!(treap.len(), 2);
treap.clear();
assert!(treap.is_empty());
assert!(!treap.contains(&1));
assert!(!treap.contains(&2));
}
#[test]
fn test_single_element() {
let mut treap = Treap::new();
let mut rng = StdRng::seed_from_u64(111);
treap.insert(42, &mut rng);
assert_eq!(treap.len(), 1);
assert!(treap.contains(&42));
assert!(!treap.contains(&0));
assert!(!treap.insert(42, &mut rng));
assert_eq!(treap.len(), 1);
assert!(treap.remove(&42));
assert!(treap.is_empty());
assert!(!treap.contains(&42));
treap.insert(42, &mut rng);
assert_eq!(treap.len(), 1);
treap.retain(|&x| x == 42);
assert_eq!(treap.len(), 1);
treap.retain(|&x| x != 42);
assert!(treap.is_empty());
}
}