From 9f9c7484c793f0c3d246086e72a3f61f4fd8e7fa Mon Sep 17 00:00:00 2001 From: Dhghomon <56599343+Dhghomon@users.noreply.github.com> Date: Sun, 26 Jul 2020 18:10:52 +0900 Subject: [PATCH] BinaryHeap --- README.md | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6fd3c58..a3b3aa8 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,8 @@ It is now late July, and *Easy Rust* is about 200 pages long. I am still writing - [Self](#self) - [Other collections](#other-collections) - [HashMap (and BTreeMap)](#hashmap-and-btreemap) - - [HashSet](#hashset) + - [HashSet and BTreeSet](#hashset-and-btreeset) + - [BinaryHeap](#binaryheap) - [Generics](#generics) - [Option and Result](#option-and-result) - [Result](#result) @@ -2948,6 +2949,84 @@ fn main() { Now it will print in order. +## BinaryHeap + +A `BinaryHeap` is an interesting collection type, because is is mostly unordered but has a bit of order. It is a collection that keeps the largest item in the front, but the other items are in any order. + +We will use another list of items for an example, but this time smaller. + +```rust +use std::collections::BinaryHeap; + +fn show_remainder(input: &BinaryHeap) -> Vec { // This function shows the remainder in the BinaryHeap. Actually an iterator would be + // faster than a function - we will learn them later. + let mut remainder_vec = vec![]; + for number in input { + remainder_vec.push(*number) + } + remainder_vec +} + +fn main() { + let many_numbers = vec![0, 5, 10, 15, 20, 25, 30]; // These numbers are in order + + let mut my_heap = BinaryHeap::new(); + + for number in many_numbers { + my_heap.push(number); + } + + while let Some(number) = my_heap.pop() { // .pop() returns Some(number) if a number is there, None if not. It pops from the front + println!("Popped off {}. Remaining numbers are: {:?}", number, show_remainder(&my_heap)); + } +} +``` + +This prints: + +```text +Popped off 30. Remaining numbers are: [25, 15, 20, 0, 10, 5] +Popped off 25. Remaining numbers are: [20, 15, 5, 0, 10] +Popped off 20. Remaining numbers are: [15, 10, 5, 0] +Popped off 15. Remaining numbers are: [10, 0, 5] +Popped off 10. Remaining numbers are: [5, 0] +Popped off 5. Remaining numbers are: [0] +Popped off 0. Remaining numbers are: [] +``` + +You can see that the number in the 0 index is always largest: 25, 20, 15, 10, 5, then 0. But the other ones are all different. + +A good way to use a `BinaryHeap` is for a collection of tasks. Here we create a `BinaryHeap` where the `u8` is a number for the importance of the task. The `&str` is a description of what to do. + +```rust +use std::collections::BinaryHeap; + +fn main() { + let mut jobs = BinaryHeap::new(); + + // Add jobs to do throughout the day + jobs.push((100, "Write back to email from the CEO")); + jobs.push((80, "Finish the report today")); + jobs.push((5, "Watch some YouTube")); + jobs.push((70, "Tell your team members thanks for always working hard")); + jobs.push((30, "Plan who to hire next for the team")); + + while let Some(job) = jobs.pop() { + println!("You need to: {}", job.1); + } +} +``` + +This will always print: + +```text +You need to: Write back to email from the CEO +You need to: Finish the report today +You need to: Tell your team members thanks for always working hard +You need to: Plan who to hire next for the team +You need to: Watch some YouTube +``` + ## Generics