From e9d0620ab5d7ba7bded1f4d435e113b39e77a375 Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Thu, 10 Dec 2020 20:04:11 -0500 Subject: [PATCH] Implement week 2 assignment 3 --- src/heap.rs | 127 +++++++++++++++++++++++++++++++++++++++++----------- src/main.rs | 5 ++- src/util.rs | 2 +- 3 files changed, 104 insertions(+), 30 deletions(-) diff --git a/src/heap.rs b/src/heap.rs index 8c26387..7251e6c 100644 --- a/src/heap.rs +++ b/src/heap.rs @@ -1,54 +1,127 @@ #[derive(Debug)] struct MinHeap { nodes: Vec, - size: usize, } -fn parent_index(i: usize) -> usize { - (i + 1) / 2 - 1 +fn parent_index(index: usize) -> usize { + (index + 1) / 2 - 1 } -fn child_index(i: usize) -> (usize, usize) { - ((i + 1) * 2 - 1, (i + 1) * 2 + 1 - 1) +fn child_indices(index: usize) -> (usize, usize) { + ((index + 1) * 2 - 1, (index + 1) * 2 + 1 - 1) } impl MinHeap { fn new() -> Self { - Self { - nodes: Vec::with_capacity(128), - size: 0, - } + Self { nodes: Vec::with_capacity(128) } + } + + fn smaller_than_parent(&self, index: usize) -> bool { + if index == 0 { + false + } else { + + self.nodes[index] < self.nodes[parent_index(index)] + } + } + + fn bubble_up(&mut self, index: usize) -> usize { + let parent_index = parent_index(index); + self.nodes.swap(index, parent_index); + parent_index } fn insert(&mut self, e: T) -> () { - // append at the end self.nodes.push(e); - self.size += 1; - let last_index = self.size - 1; - let mut swap_index = self.size - 1; + let last = self.nodes.len() - 1; + let mut bubble_index = last; - while swap_index != 0 && self.nodes[last_index] < self.nodes[parent_index(swap_index)] { - swap_index = parent_index(swap_index); + while self.smaller_than_parent(bubble_index) { + bubble_index = self.bubble_up(bubble_index); } - self.nodes.swap(last_index, swap_index); + } + + fn greater_than_children(&self, index: usize) -> bool { + let length = self.nodes.len(); + let (left_index, right_index) = child_indices(index); + if left_index < length && self.nodes[index] > self.nodes[left_index] { + true + } else if right_index < length && self.nodes[index] > self.nodes[right_index] { + true + } else { + false + } + } + + fn bubble_down(&mut self, index: usize) -> usize { + let length = self.nodes.len(); + let (left_index, right_index) = child_indices(index); + let mut target_index = index; + + if left_index < length && self.nodes[target_index] > self.nodes[left_index] { + target_index = left_index; + } + + if right_index < length && self.nodes[right_index] < self.nodes[target_index] { + target_index = right_index; + } + self.nodes.swap(index, target_index); + target_index } fn extract_min(&mut self) -> T { - if self.size == 0 { + if self.nodes.len() == 0 { panic!("Cannot extract key from empty heap"); } - self.nodes.swap(0, self.size - 1); - let child_indices = child_index(0); - println!("{:?}", child_indices); - self.nodes.pop().unwrap() + + let mut bubble_index = 0; + let last = self.nodes.len() - 1; + self.nodes.swap(bubble_index, last); + let result = self.nodes.pop().unwrap(); + + while self.greater_than_children(bubble_index) { + bubble_index = self.bubble_down(bubble_index); + } + + result + } + + fn size(&self) -> usize { + self.nodes.len() } } -pub fn heap(v: &Vec) -> () { - let mut mh: MinHeap = MinHeap::new(); - for i in 0..5 { - mh.insert(v[i]); - println!("{:?}", mh); +pub fn heap(v: &Vec) -> i32 { + let mut hl: MinHeap = MinHeap::new(); + let mut hh: MinHeap = MinHeap::new(); + + let mut iter = v.into_iter(); + let mut current_median = *iter.next().unwrap(); + let mut median_sum = current_median; + hl.insert(-current_median); + + for e in iter { + let e = *e; + if e < current_median { + hl.insert(-e); + } else { + hh.insert(e); + } + + while hl.size() < hh.size() { + let e = hh.extract_min(); + hl.insert(-e); + } + + while hl.size() > hh.size() + 1 { + let e = -hl.extract_min(); + hh.insert(e); + } + + current_median = -hl.extract_min(); + median_sum = (median_sum + current_median) % 10000; + hl.insert(-current_median); } - mh.extract_min(); + + median_sum } diff --git a/src/main.rs b/src/main.rs index b63ba49..40d10f6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,8 +42,8 @@ fn c1a4() { smallest_min_cut = new_min_cut; } } - // 17 println!("c1a4={:?}", smallest_min_cut); + // 17 } #[allow(dead_code)] @@ -71,7 +71,8 @@ fn c2a2() { #[allow(dead_code)] fn c2a3() { let vec = util::read_to_vector("data/c2a3.txt").unwrap(); - heap(&vec); + let r = heap(&vec); + println!("c2a3={:?}", r); } fn main() { diff --git a/src/util.rs b/src/util.rs index 1b45321..eab8a95 100644 --- a/src/util.rs +++ b/src/util.rs @@ -23,7 +23,7 @@ pub struct DirectedWeightedGraph { pub distance: Vec, } -pub fn read_to_vector(path: &str) -> Result, io::Error> { +pub fn read_to_vector(path: &str) -> Result, io::Error> { let file = File::open(path)?; let br = BufReader::new(file); let mut v = Vec::new();