From c536c89fff2bf29aefab443463268688f84d0fc5 Mon Sep 17 00:00:00 2001 From: Andrei Navumenka Date: Sat, 31 Aug 2024 00:42:57 -0400 Subject: [PATCH] Update mergeable_heap.rs (#205) --- rust/structures/mergeable_heap.rs | 53 +++++++++++++++---------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/rust/structures/mergeable_heap.rs b/rust/structures/mergeable_heap.rs index e50b32be..40ee8359 100644 --- a/rust/structures/mergeable_heap.rs +++ b/rust/structures/mergeable_heap.rs @@ -1,55 +1,52 @@ -use std::mem::swap; +use std::cell::RefCell; +use std::mem::{replace, swap, take}; use std::rc::Rc; struct Heap { value: V, - left: Option>>, - right: Option>>, + left: Option>>>, + right: Option>>>, } impl Heap { - fn new(value: V) -> Option>> { - Some(Rc::new(Self { + fn new(value: V) -> Option>>> { + Some(Rc::new(RefCell::new(Self { value, left: None, right: None, - })) + }))) } - fn merge(a: &Option>>, b: &Option>>) -> Option>> { + fn merge<'a>( + mut a: &'a Option>>>, + mut b: &'a Option>>>, + ) -> Option>>> { if a.is_none() { return b.clone(); } if b.is_none() { return a.clone(); } - let mut ra = a.clone()?; - let mut rb = b.clone()?; - if ra.value > rb.value { - swap(&mut ra, &mut rb); + if a.as_ref()?.borrow().value > b.as_ref()?.borrow().value { + swap(&mut a, &mut b); } if rand::random() { - ra = Rc::new(Heap { - value: ra.value.clone(), - left: ra.right.clone(), - right: ra.left.clone(), - }); + let mut ra = a.as_ref()?.borrow_mut(); + let l = take(&mut ra.left); + let r = take(&mut ra.right); + ra.left = r; + ra.right = l; } - Some(Rc::new(Heap { - value: ra.value.clone(), - left: Self::merge(&ra.left.clone(), &Some(rb)), - right: ra.right.clone(), - })) + let m = Self::merge(replace(&mut &a.as_ref()?.borrow_mut().left, &None), b); + a.as_ref()?.borrow_mut().left = m; + a.clone() } - fn remove_min(heap: &Option>>) -> (Option>>, V) { - let h = heap.as_ref().unwrap(); - ( - Self::merge(&h.as_ref().left, &h.as_ref().right), - h.as_ref().value.clone(), - ) + fn remove_min(heap: &Option>>>) -> (Option>>>, V) { + let h = heap.as_ref().unwrap().borrow(); + (Self::merge(&h.left, &h.right), h.value.clone()) } - fn add(heap: &Option>>, value: V) -> Option>> { + fn add(heap: &Option>>>, value: V) -> Option>>> { Self::merge(heap, &Heap::new(value)) } }