Skip to content

Commit b22fbce

Browse files
committed
Add optimized from_list method
1 parent b39f5ab commit b22fbce

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

src/almost_perfect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fn leaf<T: Clone>(w: Weight, a: T) -> Tree<T> {
3535
}
3636

3737
/// Builds an almost perfect tree using the weights and values in `elems`
38-
fn almost_perfect<T: Clone>(elems: Vec<(Weight, T)>) -> Tree<T> {
38+
pub fn almost_perfect<T: Clone>(elems: Vec<(Weight, T)>) -> Tree<T> {
3939
/// Helper function: recurses on the current `depth` of the tree
4040
/// and the array `elem`s, either inserting two elements at a time
4141
/// or one at a time

src/urn.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
#![allow(dead_code)]
22

3-
use crate::types::{Index, Tree, Tree::*, Urn, Weight};
3+
use crate::{
4+
almost_perfect::almost_perfect,
5+
types::{
6+
Index,
7+
Tree::{self, *},
8+
Urn, Weight,
9+
},
10+
};
411

512
/* -------------------------------------------------------------------------- */
613
/* Helpers */
@@ -38,8 +45,8 @@ fn singleton<T: Clone>(w: Weight, a: T) -> Urn<T> {
3845
/// Naive implementation of `from_list`, which just folds `insert` over a
3946
/// vector of (weight, element) pairs.
4047
/// TODO: add QC property that says `from_list` behaves the same as `from_list_naive`
41-
fn from_list_naive<T: Clone>(elts: Vec<(Weight, T)>) -> Option<Urn<T>> {
42-
match elts.as_slice() {
48+
fn from_list_naive<T: Clone>(elems: Vec<(Weight, T)>) -> Option<Urn<T>> {
49+
match elems.as_slice() {
4350
[] => None,
4451
[(w, a), ws @ ..] => Some(
4552
ws.iter()
@@ -50,6 +57,19 @@ fn from_list_naive<T: Clone>(elts: Vec<(Weight, T)>) -> Option<Urn<T>> {
5057
}
5158
}
5259

60+
/// An optimized version of `from_list`, which builds an almost perfect tree
61+
/// in linear time (see `almost_perfect.rs`)
62+
fn from_list<T: Clone>(elems: Vec<(Weight, T)>) -> Option<Urn<T>> {
63+
if elems.is_empty() {
64+
None
65+
} else {
66+
Some(Urn {
67+
size: elems.len() as u32,
68+
tree: almost_perfect(elems),
69+
})
70+
}
71+
}
72+
5373
impl<T: Clone> Urn<T> {
5474
/// Fetches the `size` of the urn
5575
fn size(&self) -> u32 {

0 commit comments

Comments
 (0)