Created
January 9, 2019 15:16
-
-
Save pftbest/7ad3069461a173d951860a80a3015a50 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![allow(non_snake_case)] | |
use rand::seq::SliceRandom; | |
use std::time::Instant; | |
use std::ops::Deref; | |
pub struct NonEmptyMaxHeap<T> { | |
elements: Vec<T>, | |
} | |
impl<T: Ord + Copy> NonEmptyMaxHeap<T> { | |
pub fn init(root: T) -> Self { | |
NonEmptyMaxHeap { elements: vec![root] } | |
} | |
pub fn insert(&mut self, element: T) { | |
let mut index = self.elements.len(); | |
self.elements.push(element); | |
while index > 0 { | |
let parentIndex = (index - 1) / 2; | |
let parent = self.elements[parentIndex]; | |
if !(parent < element) { break } | |
self.elements[index] = parent; | |
index = parentIndex; | |
} | |
self.elements[index] = element; | |
} | |
pub fn root(&self) -> T { | |
self.elements[0] | |
} | |
pub fn replaceRoot(&mut self, element: T) { | |
let mut index = 0; | |
let mut childIndex = 2 * index + 1; | |
while childIndex < self.elements.len() { | |
let mut child = self.elements[childIndex]; | |
let rightIndex = childIndex + 1; | |
if rightIndex < self.elements.len() { | |
let right = self.elements[rightIndex]; | |
if child < right { | |
child = right; | |
childIndex = rightIndex; | |
} | |
} | |
if !(element < child) { break } | |
self.elements[index] = child; | |
index = childIndex; | |
childIndex = 2 * index + 1; | |
} | |
self.elements[index] = element; | |
} | |
} | |
trait Smallest<T> { | |
fn smallest(&self, n: usize) -> Vec<T>; | |
} | |
impl<T, I> Smallest<T> for I where T: Ord + Copy, I: Deref<Target = [T]> { | |
fn smallest(&self, n: usize) -> Vec<T> { | |
let mut iterator = self.iter().cloned(); | |
let first = match iterator.next() { | |
Some(first) => first, | |
None => return Vec::new(), | |
}; | |
let mut heap = NonEmptyMaxHeap::init(first); | |
let mut heapSize = 1; | |
while heapSize < n { | |
if let Some(element) = iterator.next() { | |
heap.insert(element); | |
heapSize += 1; | |
} else { | |
break; | |
} | |
} | |
while let Some(element) = iterator.next() { | |
if element < heap.root() { | |
heap.replaceRoot(element); | |
} | |
} | |
heap.elements.sort_unstable(); | |
heap.elements | |
} | |
} | |
fn main() { | |
let n = 1_000_000; | |
let k = 1000; | |
let mut rng = rand::thread_rng(); | |
let mut vec: Vec<_> = (0..n).collect(); | |
vec.shuffle(&mut rng); | |
let start = Instant::now(); | |
let smallest = vec.smallest(k); | |
println!("{:?}", start.elapsed()); | |
assert!(smallest.into_iter().eq(0..k)); | |
assert!(vec.len() == n); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment