Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
174
third-party/vendor/slotmap/examples/rand_meld_heap.rs
vendored
Normal file
174
third-party/vendor/slotmap/examples/rand_meld_heap.rs
vendored
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
// Randomized meldable heap.
|
||||
// https://en.wikipedia.org/wiki/Randomized_meldable_heap
|
||||
|
||||
use slotmap::{new_key_type, Key, SlotMap};
|
||||
|
||||
new_key_type! {
|
||||
struct HeapKey;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct NodeHandle(HeapKey);
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct Node<T> {
|
||||
value: T,
|
||||
children: [HeapKey; 2],
|
||||
parent: HeapKey,
|
||||
}
|
||||
|
||||
struct RandMeldHeap<T: Ord> {
|
||||
sm: SlotMap<HeapKey, Node<T>>,
|
||||
rng: std::num::Wrapping<u32>,
|
||||
root: HeapKey,
|
||||
}
|
||||
|
||||
impl<T: Ord + std::fmt::Debug> RandMeldHeap<T> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
sm: SlotMap::with_key(),
|
||||
rng: std::num::Wrapping(0xdead_beef),
|
||||
root: HeapKey::null(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn coinflip(&mut self) -> bool {
|
||||
// Simple LCG for top speed - random quality barely matters.
|
||||
self.rng += (self.rng << 8) + std::num::Wrapping(1);
|
||||
self.rng >> 31 > std::num::Wrapping(0)
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, value: T) -> NodeHandle {
|
||||
let k = self.sm.insert(Node {
|
||||
value,
|
||||
children: [HeapKey::null(), HeapKey::null()],
|
||||
parent: HeapKey::null(),
|
||||
});
|
||||
|
||||
let root = self.root;
|
||||
self.root = self.meld(k, root);
|
||||
|
||||
NodeHandle(k)
|
||||
}
|
||||
|
||||
pub fn pop(&mut self) -> Option<T> {
|
||||
self.sm.remove(self.root).map(|root| {
|
||||
self.root = self.meld(root.children[0], root.children[1]);
|
||||
if let Some(new_root) = self.sm.get_mut(self.root) {
|
||||
new_root.parent = HeapKey::null();
|
||||
}
|
||||
|
||||
root.value
|
||||
})
|
||||
}
|
||||
|
||||
pub fn remove_key(&mut self, node: NodeHandle) -> T {
|
||||
let node = node.0;
|
||||
self.unlink_node(node);
|
||||
self.sm.remove(node).unwrap().value
|
||||
}
|
||||
|
||||
pub fn update_key(&mut self, node: NodeHandle, value: T) {
|
||||
let node = node.0;
|
||||
|
||||
// Unlink and re-insert.
|
||||
self.unlink_node(node);
|
||||
self.sm[node] = Node {
|
||||
value,
|
||||
children: [HeapKey::null(), HeapKey::null()],
|
||||
parent: HeapKey::null(),
|
||||
};
|
||||
let root = self.root;
|
||||
self.root = self.meld(node, root);
|
||||
}
|
||||
|
||||
fn unlink_node(&mut self, node: HeapKey) {
|
||||
// Remove node from heap by merging children and placing them where
|
||||
// node used to be.
|
||||
let children = self.sm[node].children;
|
||||
let parent_key = self.sm[node].parent;
|
||||
|
||||
let melded_children = self.meld(children[0], children[1]);
|
||||
if let Some(mc) = self.sm.get_mut(melded_children) {
|
||||
mc.parent = parent_key;
|
||||
}
|
||||
|
||||
if let Some(parent) = self.sm.get_mut(parent_key) {
|
||||
if parent.children[0] == node {
|
||||
parent.children[0] = melded_children;
|
||||
} else {
|
||||
parent.children[1] = melded_children;
|
||||
}
|
||||
} else {
|
||||
self.root = melded_children;
|
||||
}
|
||||
}
|
||||
|
||||
fn meld(&mut self, mut a: HeapKey, mut b: HeapKey) -> HeapKey {
|
||||
if a.is_null() {
|
||||
return b;
|
||||
}
|
||||
if b.is_null() {
|
||||
return a;
|
||||
}
|
||||
|
||||
if self.sm[a].value > self.sm[b].value {
|
||||
std::mem::swap(&mut a, &mut b);
|
||||
}
|
||||
|
||||
let ret = a;
|
||||
|
||||
// From this point parent and trickle are assumed to be valid keys.
|
||||
let mut parent = a;
|
||||
let mut trickle = b;
|
||||
|
||||
loop {
|
||||
// If a child spot is free, put our trickle there.
|
||||
let children = self.sm[parent].children;
|
||||
if children[0].is_null() {
|
||||
self.sm[parent].children[0] = trickle;
|
||||
self.sm[trickle].parent = parent;
|
||||
break;
|
||||
} else if children[1].is_null() {
|
||||
self.sm[parent].children[1] = trickle;
|
||||
self.sm[trickle].parent = parent;
|
||||
break;
|
||||
}
|
||||
|
||||
// No spot free, choose a random child.
|
||||
let c = self.coinflip() as usize;
|
||||
let child = children[c];
|
||||
if self.sm[child].value > self.sm[trickle].value {
|
||||
self.sm[parent].children[c] = trickle;
|
||||
self.sm[trickle].parent = parent;
|
||||
parent = trickle;
|
||||
trickle = child;
|
||||
} else {
|
||||
parent = child;
|
||||
}
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.sm.len()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut rhm = RandMeldHeap::new();
|
||||
let the_answer = rhm.insert(-2);
|
||||
let big = rhm.insert(999);
|
||||
|
||||
for k in (0..10).rev() {
|
||||
rhm.insert(k * k);
|
||||
}
|
||||
|
||||
rhm.update_key(the_answer, 42);
|
||||
rhm.remove_key(big);
|
||||
|
||||
while rhm.len() > 0 {
|
||||
println!("{}", rhm.pop().unwrap());
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue