Skip to content

Instantly share code, notes, and snippets.

@pftbest
Created January 9, 2019 15:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pftbest/7ad3069461a173d951860a80a3015a50 to your computer and use it in GitHub Desktop.
Save pftbest/7ad3069461a173d951860a80a3015a50 to your computer and use it in GitHub Desktop.
#![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