Browse Source

hw5 mostly finished, gave up

master
LER0ever 7 months ago
parent
commit
9294f4636d
3 changed files with 1113 additions and 24 deletions
  1. 2
    0
      hw5/hw5-problems/Cargo.lock
  2. 685
    0
      hw5/hw5-problems/src/lib.bak.rs
  3. 426
    24
      hw5/hw5-problems/src/lib.rs

+ 2
- 0
hw5/hw5-problems/Cargo.lock View File

@@ -1,3 +1,5 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "autocfg"
version = "0.1.2"

+ 685
- 0
hw5/hw5-problems/src/lib.bak.rs View File

@@ -0,0 +1,685 @@
/*
* CS 538, Spring 2019: HW5
*
* Binary Search Tree
* See `bst.md` for the overview.
*/

#![allow(dead_code)]
#![forbid(unsafe_code)]

use std::cmp::Ordering;
use std::fmt::Debug;
use std::iter::{FromIterator, IntoIterator};
use std::ops::{Bound, Index, IndexMut};

/// Type of BST nodes.
#[derive(Debug)]
struct Node<K, V> {
key: K,
val: V,
size: usize,
lt: TreeMap<K, V>,
rt: TreeMap<K, V>,
}

/// Type of BSTs.
///
/// See TMLL 2.1 for details about the memory layout if you are curious.
#[derive(Debug, Default)]
pub struct TreeMap<K, V> {
inner: Option<Box<Node<K, V>>>,
instance: bool
// TODO: GRADER!!!
// I'm using this variable to store Option state,
// so that I can use unwrap() everytime
// I'm sure it will not panic
}

/// Part 1: Basic operations and traits (50)
///
/// Your first task is to implement the following operations on BSTs.
///
/// The API here is modeled after Rust's standard BTreeMap collections type. The implementation
/// details are up to you, but you should not change the types of public functions.
impl<K, V> TreeMap<K, V>
where
K: Ord + Debug,
V: Debug,
{
/// Make a new TreeMap.
pub fn new() -> Self {
TreeMap{ inner:None, instance:false }
}

/// Clear a TreeMap.
pub fn clear(&mut self) {
// self.inner = None;
// self.size = 0;
*self = TreeMap::new();
}

/// Check if a TreeMap is empty.
pub fn is_empty(&self) -> bool {
self.instance
}

/// Compute the size of a TreeMap.
pub fn len(&self) -> usize {
if !self.instance { return 0; }
let root = self.inner.as_ref().unwrap();
return root.size;
// if !self.instance { return 0; }
// let root = &self.inner.as_ref().unwrap();
// // I gave up on the no recursion challenge...
// return 1 + TreeMap::len(&root.lt) + TreeMap::len(&root.rt);
}

fn update_size(&mut self) -> usize {
// this function it very expensive, it cascade down the entire tree to update every size
// there should be a better way to do it in place while changing
// but I'm running outta time.
if !self.instance { return 0; }
let root = self.inner.as_mut().unwrap();
root.size = 1 + TreeMap::update_size(&mut root.lt) + TreeMap::update_size(&mut root.rt);
return root.size;
}

fn update_level_size(&mut self) -> usize {
if !self.instance { return 0; }
let root = self.inner.as_mut().unwrap();
root.size = 1 + TreeMap::len(&root.lt) + TreeMap::len(&root.rt);
return root.size;
}

/// Check if a TreeMap has a certain key.
pub fn has_key(&self, key: &K) -> bool {
if !self.instance { return false; }
let root = &self.inner.as_ref().unwrap();
if key.eq(&root.key) { return true; }
if key.lt(&root.key) { return TreeMap::has_key(&root.lt, key); }
else { return TreeMap::has_key(&root.rt, key); }
}

/// Get a reference to the value associated with a key, if present.
///
/// If the key is not in the map, return None.
pub fn get(&self, key: &K) -> Option<&V> {
if !self.instance { return None; }
let root = self.inner.as_ref().unwrap();
if key.eq(&root.key) { return Some(&root.val); }
if key.lt(&root.key) { return TreeMap::get(&root.lt, key); }
else { return TreeMap::get(&root.rt, key); }
}

/// Get a mutable reference to the value associated with a key, if present.
///
/// If the key is not in the map, return None.
pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
if !self.instance { return None; }
let root = self.inner.as_mut().unwrap();
if key.eq(&root.key) { return Some(&mut root.val); }
if key.lt(&root.key) { return TreeMap::get_mut(&mut root.lt, key); }
else { return TreeMap::get_mut(&mut root.rt, key); }
}

/// Insert a (key, value) pair into a TreeMap.
///
/// If the key is already present in the map, return the previous value and replace the old
/// value with the new value. Otherwise, insert the new (key, value) pair and return None.
pub fn insert(&mut self, key: K, val: V) -> Option<V> {
if !self.instance {
println!("no instance, creating one!");
self.inner = Some(Box::new(Node { key: key, val: val, size: 1, lt: TreeMap::new(), rt: TreeMap::new() }));
self.instance = true;
return None;
} else {
let root = self.inner.as_mut().unwrap();
if key.eq(&root.key) {
println!("found target, doing replacing");
let oldval = std::mem::replace(&mut root.val, val); return Some(oldval);
}
if key.lt(&root.key) {
println!("target < key, going left...");
match TreeMap::insert(&mut root.lt, key, val) {
Some(v) => { return Some(v); },
None => { TreeMap::update_level_size(self); return None; },
}
}
else {
println!("target > key, going right...");
match TreeMap::insert(&mut root.rt, key, val) {
Some(v) => { return Some(v); },
None => { TreeMap::update_level_size(self); return None; },
}
}
}
}

/// Insert a nonempty TreeMap into a TreeMap.
///
/// While real BSTs do careful rotations/rebalancing to keep the depth of the merged tree as
/// small as possible, we will just do a naive insert by going down to an appropriate leaf of
/// `self` and sticking `other` there.
///
/// Since this function is not publicly visible (there is no `pub` before `fn`), it is not used
/// directly by clients. You may assume that `self` and `other` are non-overlapping: either all
/// nodes in self are strictly smaller than all nodes in other, or all nodes in self are
/// strictly larger than all nodes in other. Your implementation can panic (or just continue
/// silently) if this requirement is not met. However if the trees are not overlapping, you
/// must maintain the BST invariant.
fn insert_tree(&mut self, mut other: Self) {
if !self.instance {
println!("no instance, creating one!"); // really should panic here
self.inner = other.inner.take();
self.instance = true;
TreeMap::update_size(self);
} else {
if !other.instance { return }
let root = self.inner.as_mut().unwrap();
let other_root = other.inner.as_mut().unwrap();
if other_root.key.lt(&root.key) {
println!("target < key, going left...");
TreeMap::insert_tree(&mut root.lt, other);
TreeMap::update_level_size(self);
}
else {
println!("target > key, going right...");
TreeMap::insert_tree(&mut root.rt, other);
TreeMap::update_level_size(self);
}
}
}

/// Remove a key from a TreeMap.
///
/// If the map contains the key, remove the key and return the associated value.
/// If the map does not contain the key, return None and leave the map unchanged.
///
/// Hint: take the two child trees of the node you're removing, insert one into the other.
pub fn remove(&mut self, key: K) -> Option<V> {
return TreeMap::remove_helper(self, key);


// match TreeMap::remove_helper(self, key) {
// None => { return None; }
// Some(root) => {
// let taken_inner = root.inner.take();
// let unwrapped_inner = taken_inner.unwrap();
// let v = unwrapped_inner.val;
// root.clear();
// TreeMap::insert_tree(self, unwrapped_inner.lt);
// TreeMap::insert_tree(self, unwrapped_inner.rt);
// TreeMap::update_size(self);
// return Some(v);
// }
// }

}

fn remove_helper(&mut self, key: K) -> Option<V> {
if !TreeMap::has_key(self, &key) { return None; }
if !self.instance { return None; }
let root = self.inner.as_mut().unwrap();
let v:V;
if key.eq(&root.key) {
v=self.inner.unwrap().val;
self.inner.replace(root.lt.inner.unwrap());
self.insert_tree(root.rt);
return Some(v);
}
if key.lt(&root.key) { return TreeMap::remove_helper(&mut root.lt, key); }
else { return TreeMap::remove_helper(&mut root.rt, key); }
}
}

/// We will implement a few traits for TreeMap. Starting off: implement the FromIterator trait.
///
/// Hint: feed stuff from the iterator into the TreeMap.
impl<K, V> FromIterator<(K, V)> for TreeMap<K, V>
where
K: Ord + Debug,
V: Debug,
{
fn from_iter<T>(iter: T) -> TreeMap<K, V>
where
T: IntoIterator<Item = (K, V)>,
{
unimplemented!()
}
}

/// Now, we will implement two kinds of indexing traits: Index and IndexMut.
///
/// Rust's built-in syntactic sugar hooks into these traits, for instance we can write stuff like:
///
/// let val = map[idx];
///
/// which is short for
///
/// let val = *map.index(idx);
///
/// if we have the Index trait. If we implement the IndexMut trait, we can write stuff like:
///
/// map[idx] = new_val;
///
/// which is short for
///
/// *map.index(idx) = new_val;
///
/// Index returns a reference to the value for a given key, and IndexMut returns a mutable
/// reference to the value for a given key. If the key is not in the map, panic. You will probably
/// want to take a look at the documentation for Index and IndexMut.
///
/// Note: the Rust BTreeMap actually has a more general type for these operations, something like:
///
/// fn index<Q>(&self, key: &Q) -> &V
/// where
/// K: Borrow<Q>,
/// Q: Ord + ?Sized,
/// { ... }
///
/// The idea here is that K is the key type stored in the map, while Q is the key type used for
/// lookups. In some cases, this allows us to avoid constructing a new object just to do a lookup;
/// think K = String and Q = &str. The trait bound K: Borrow<Q> says that if we have a K, we can
/// get a reference to Q. The Then, we can compare Q's since Q: Ord. (The question-mark bound Q:
/// ?Sized means that the size of Q does *not* need to be known at compile time; by default, all
/// type parameters have statically known sizes.) See the documentation for Borrow for an example
/// of how this works:
///
/// https://doc.rust-lang.org/std/borrow/trait.Borrow.html
impl<'a, K, V> Index<&'a K> for TreeMap<K, V>
where
K: Ord + Debug,
V: Debug,
{
type Output = V;

fn index(&self, key: &K) -> &V {
unimplemented!()
}
}

impl<'a, K, V> IndexMut<&'a K> for TreeMap<K, V>
where
K: Ord + Debug,
V: Debug,
{
fn index_mut(&mut self, key: &'a K) -> &mut V {
unimplemented!()
}
}

/// Part 2: Iterators (35)
///
/// Now, you will soup up your BST by implementing various kinds of iterators to perform in-order
/// traversals of the map, i.e., from smallest to largest key.
///
/// The first iterator you will design is a so-called *consuming iterator*, which takes ownership
/// of all elements in the map. You will use the following types to track the current state of the
/// iterator:

enum Next<I, T> {
Item(I),
Tree(T),
}

pub struct IntoIter<K, V> {
next_nodes: Vec<Next<(K, V), TreeMap<K, V>>>,
current_val: Option<(K, V)>,
}

/// This state has two main parts. There is the current key value pair (or nothing, if the iterator
/// is already finished), and stack of `Next` recording the next elements of the iterator. For
/// instance, if the iterator is currently at a node that is a left-child of its parent, the top of
/// the stack would be the data at the parent, the 2nd-from-top of the stack would store the whole
/// subtree from the right sibling, and so on.
///
/// Define a few functions to set up the consuming iterator.
impl<K, V> IntoIter<K, V> {
/// Make a new consuming iterator from a TreeMap
///
/// Note that this function takes ownership (i.e., tree is passed by value). This is fine,
/// because we are building a *consuming* iterator.
fn new(tree: TreeMap<K, V>) -> Self {
unimplemented!()
}

/// This is the main workhorse function for setting up the iterator. In words, this function
/// should descends to the left-furthermost non-leaf child. Along the way, it sets up the
/// iterator state: the current value, and the next-nodes-to-visit stack. Make sure you add
/// nodes in the right order: we are aiming for an in-order traversal, so the iterator should
/// visit left-child, parent, right-child as we pop things off the stack.
fn descend_left(&mut self, tree: TreeMap<K, V>) {
unimplemented!()
}
}

/// Implement IntoIterator for TreeMap.
impl<K, V> IntoIterator for TreeMap<K, V> {
type Item = (K, V);
type IntoIter = IntoIter<K, V>;

fn into_iter(self) -> IntoIter<K, V> {
unimplemented!()
}
}

/// Now, we are ready to implement the Iterator trait for IntoIter.
///
/// The main function `next` should get the current value, update the iterator to prepare the next
/// value, and then update the nodes to visit.
///
/// Hint: you'll want to use `descend_left`.
impl<K, V> Iterator for IntoIter<K, V> {
type Item = (K, V);
fn next(&mut self) -> Option<Self::Item> {
unimplemented!()
}
}

/// Now, you'll define a few variants of iterators that do not consume the data. These are also
/// called *borrowing* iterators, since they borrow data instead of consuming it. The overall
/// strategy will be quite similar to what you already did above, but with a few tweaks. The main
/// idea behind a borrowing iterator is that we should produce references to data, rather than data.
///
/// For this part, you'll be designing the type structures and implementing the necessary functions.
/// You should design two kinds of iterators:
///
/// 1. Borrowing iterator. This should implement the Iterator trait with item type (&K, &V).
/// 2. Mutable iterator. This should implement the Iterator trait with item type (&K, &mut V).
///
/// Note that we need to be a bit careful with mutable iterators: clients should be allowed to
/// modify the value, but they should not be allowed to modify the keys---if they did, they might
/// screw up the BST property. Your mutable iterator should hand out a pair of references: an
/// *immutable* reference to the key, and a *mutable* reference to the value.
///
/// To construct these two iterators, implement the following two methods for TreeMap:
///
/// 1. pub fn iter(&self) -> Iter<K, V>
/// 2. pub fn iter_mut(&mut self) -> IterMut<K, V>
///
/// Iter and IterMut should implement the Iterator trait.
///
/// You should also implement versions of all the associated functions you did for IntoIter, but do
/// not implement IntoIterator for TreeMap again.
///
/// Hint: don't implement these iterators from scratch. You'll need to sprinkle in some extra
/// annotations and tweaks in a few key places, but your code for the borrowing and mutable
/// iterators should be a nearly exact copy-paste of your code for consuming iterators.

/// Part 3: Custom dropping (15)
///
/// The built-in Drop trait behaves poorly because it drops TreeMap recursively. If the TreeMap
/// too deep, this will blow up the stack when dropping (see TMLL 2.7 for details).
///
/// Implement a custom Drop trait to drop the TreeMap in a loop rather than recursing. The default
/// Drop implementation for the TreeMap/Node types drops according to a *pre-order* traversal: drop
/// root, then drop left, then drop right. Your implementation should maintain this order.
impl<K, V> Drop for TreeMap<K, V> {
fn drop(&mut self) {
// unimplemented!()
}
}

#[cfg(test)]
mod test {
use super::TreeMap;
use std::fmt::Debug;

impl<K, V> TreeMap<K, V>
where
K: Ord + Debug,
V: Debug,
{
/// Test function: checks the BST invariant.
fn is_bst(&self) -> bool {
let mut lsize = 0;
let mut rsize = 0;
if let Some(boxed) = &self.inner {
let lt = &boxed.lt;
let rt = &boxed.rt;

if let Some(lnode) = &lt.inner {
if lnode.key >= boxed.key || !lt.is_bst() {
return false;
}

lsize = lnode.size;
}

if let Some(rnode) = &rt.inner {
if rnode.key <= boxed.key || !rt.is_bst() {
return false;
}

rsize = rnode.size;
}

return boxed.size == lsize + rsize + 1;
}

true
}
}

#[test]
fn test_insert() {
let mut tree = TreeMap::new();

tree.insert(1, 11);
tree.insert(3, 33);
tree.insert(2, 22);

assert_eq!(tree.get(&1), Some(&11));
assert_eq!(tree.get(&2), Some(&22));
assert_eq!(tree.get(&3), Some(&33));

assert!(tree.is_bst());

let insert_res = tree.insert(1, 111);

assert_eq!(tree.get(&1), Some(&111));
assert_eq!(insert_res, Some(11));

assert!(tree.is_bst());
}

#[test]
fn test_clear() {
let mut tree = TreeMap::new();

tree.insert(1, 11);
tree.insert(3, 33);
tree.insert(2, 22);

assert_eq!(tree.len(), 3);

tree.clear();

assert_eq!(tree.len(), 0);
}

#[test]
fn test_remove() {
let mut tree = TreeMap::new();

tree.insert(1, 11);
tree.insert(3, 33);
tree.insert(2, 22);

assert_eq!(tree.remove(1), Some(11));
assert_eq!(tree.len(), 2);
assert!(tree.is_bst());

assert_eq!(tree.remove(1), None);
assert_eq!(tree.len(), 2);
assert!(tree.is_bst());
}

#[test]
fn test_mut() {
let mut tree = TreeMap::new();

tree.insert(1, 11);
tree.insert(3, 33);
tree.insert(2, 22);

assert_eq!(tree.get(&3), Some(&33));

*tree.get_mut(&3).unwrap() = 333;

assert_eq!(tree.get(&3), Some(&333));

assert!(tree.is_bst());
}

#[test]
fn test_index() {
let mut tree = TreeMap::new();

tree.insert(1, 11);
tree.insert(3, 33);
tree.insert(2, 22);

assert_eq!(tree[&1], 11);

tree[&2] = 22;

assert_eq!(tree.get(&2), Some(&22));

assert!(tree.is_bst());
}

#[should_panic]
#[test]
fn test_bad_index() {
let mut tree = TreeMap::new();

tree.insert(1, 11);
tree.insert(3, 33);
tree.insert(2, 22);

tree[&5] = 10;
}

#[test]
fn test_from_iter() {
let vec = vec![(1, 11), (3, 33), (2, 22)];
let tree: TreeMap<i32, i32> = vec.into_iter().collect();

assert!(tree.is_bst());

assert_eq!(tree.get(&1), Some(&11));
assert_eq!(tree.get(&2), Some(&22));
assert_eq!(tree.get(&3), Some(&33));
}

#[test]
fn test_iter() {
let vec = vec![(1, 11), (3, 33), (2, 22)];
let tree: TreeMap<i32, i32> = vec.into_iter().collect();

let mut iter = tree.into_iter();

assert_eq!(iter.next(), Some((1, 11)));
assert_eq!(iter.next(), Some((2, 22)));
assert_eq!(iter.next(), Some((3, 33)));
assert_eq!(iter.next(), None);
}

/* Uncomment when borrowing iterator ready.
#[test]
fn test_borrow_iter() {
let vec = vec![(1, 11), (3, 33), (2, 22)];
let tree: TreeMap<i32, i32> = vec.into_iter().collect();

let mut iter = tree.iter();

assert_eq!(iter.next(), Some((&1, &11)));
assert_eq!(iter.next(), Some((&2, &22)));
assert_eq!(iter.next(), Some((&3, &33)));
assert_eq!(iter.next(), None);
} */

/* Uncomment when mutable iterator ready.
#[test]
fn test_mut_iter() {
let vec = vec![(1, 11), (3, 33), (2, 22)];
let mut tree: TreeMap<i32, i32> = vec.into_iter().collect();

for (k, v) in tree.iter_mut() {
*v = k + 100;
}

assert!(tree.is_bst());
assert_eq!(tree.len(), 3);

assert_eq!(tree.get(&1), Some(&101));
assert_eq!(tree.get(&2), Some(&102));
assert_eq!(tree.get(&3), Some(&103));
} */

use std::cell::RefCell;

#[derive(Debug)]
struct MyDropper<'a> {
inner: String,
log: &'a RefCell<Vec<String>>,
}

impl<'a> Drop for MyDropper<'a> {
fn drop(&mut self) {
// Record the dropped String in a shared log
let newstr = self.inner.clone();
self.log.borrow_mut().push(newstr);
}
}

#[test]
fn test_drop() {
let drops = RefCell::new(vec![]);

// Contents of tree in pre-order traversal
let contents = vec![
String::from("m"),
String::from("h"),
String::from("a"),
String::from("k"),
String::from("t"),
String::from("p"),
String::from("z"),
];

// Set up a complete binary tree (key = val)
{
let mut tree = TreeMap::new();
for s in &contents {
let log = &drops;
let key = s.clone();
let inner = s.clone();
tree.insert(key, MyDropper { inner, log });
}
} // ... and drop it

// Check the order of drops
assert_eq!(*drops.borrow(), contents);
}

/* Uncomment when drop trait ready.
#[test]
fn test_drop_big() {
// This is slow (~1-2 min on my machine) but it shouldn't overflow!
let v = (1..100000).collect::<Vec<u32>>();

// Make a really deep binary tree
{
let mut tree = TreeMap::new();
for i in v {
tree.insert(i, i);
}
} // ... and drop it

println!("All done!");
} */
}

+ 426
- 24
hw5/hw5-problems/src/lib.rs View File

@@ -37,6 +37,55 @@ pub struct TreeMap<K, V> {
///
/// The API here is modeled after Rust's standard BTreeMap collections type. The implementation
/// details are up to you, but you should not change the types of public functions.
///

impl<K,V> Node<K,V>
where
K: Ord + Debug,
V: Debug,
{
pub fn find(&self, key: &K) -> Option<Box<&Node<K, V>>> {
if key.lt(&self.key) {
match self.lt.inner {
None => None,
Some(ref sn) => {
sn.find(key)
},
}
} else if key.gt(&self.key) {
match self.rt.inner {
None => None,
Some(ref sn) => {
sn.find(key)
}
}
} else {
Some(Box::from(self))
}
}

pub fn find_mut(&mut self, key: &K) -> Option<Box<&mut Node<K,V>>> {
if key.lt(&mut self.key) {
match self.lt.inner {
None => None,
Some(ref mut sn) => {
sn.find_mut(key)
},
}
} else if key.gt(&mut self.key) {
match self.rt.inner {
None => None,
Some(ref mut sn) => {
sn.find_mut(key)
}
}
} else {
Some(Box::from(self))
}
}

}

impl<K, V> TreeMap<K, V>
where
K: Ord + Debug,
@@ -44,41 +93,100 @@ where
{
/// Make a new TreeMap.
pub fn new() -> Self {
unimplemented!()
TreeMap{
inner: None,
}
}

/// Clear a TreeMap.
pub fn clear(&mut self) {
unimplemented!()
*self = TreeMap::new();
}

/// Check if a TreeMap is empty.
pub fn is_empty(&self) -> bool {
unimplemented!()
match self.inner {
None => true,
Some(ref n) => n.size != 0,
}
}

/// Compute the size of a TreeMap.
pub fn len(&self) -> usize {
unimplemented!()
match self.inner {
None => 0,
Some(ref n) => n.size,
}
}

fn find(&self, key: &K) -> Option<Box<&Node<K,V>>> {
match self.inner {
None => None,
Some(ref n) => n.find(key),
}
}

fn find_mut(&mut self, key: &K) -> Option<Box<&mut Node<K,V>>> {
match self.inner {
None => None,
Some(ref mut n) => n.find_mut(key),
}
}

fn update_size(&mut self) -> usize {
match self.inner {
None => 0,
Some(ref mut n) => {
n.size = 1 + n.lt.update_size() + n.rt.update_size();
return n.size;
}
}
}

fn update_level_size(&mut self) -> usize {
match self.inner {
None => 0,
Some(ref mut n) => {
n.size = 1 + n.lt.len() + n.rt.len();
return n.size;
}
}
}
/// Check if a TreeMap has a certain key.
pub fn has_key(&self, key: &K) -> bool {
unimplemented!()
match self.find(key) {
None => false,
_ => true,
}
}

/// Get a reference to the value associated with a key, if present.
///
/// If the key is not in the map, return None.
pub fn get(&self, key: &K) -> Option<&V> {
unimplemented!()
match self.inner {
None => None,
Some(ref n) => {
if key.lt(&n.key) { return n.lt.get(key); }
else if key.gt(&n.key) { return n.rt.get(key); }
else { return Some(& n.val); }
},
}
}

/// Get a mutable reference to the value associated with a key, if present.
///
/// If the key is not in the map, return None.
pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
unimplemented!()
match self.inner {
None => None,
Some(ref mut n) => {
if key.lt(&n.key) { return n.lt.get_mut(key); }
else if key.gt(&n.key) { return n.rt.get_mut(key); }
else { return Some(&mut n.val); }
},
}
}

/// Insert a (key, value) pair into a TreeMap.
@@ -86,7 +194,28 @@ where
/// If the key is already present in the map, return the previous value and replace the old
/// value with the new value. Otherwise, insert the new (key, value) pair and return None.
pub fn insert(&mut self, key: K, val: V) -> Option<V> {
unimplemented!()
match self.inner {
None => {
self.inner = Some(Box::new(Node { key: key, val: val, size: 1, lt: TreeMap::new(), rt: TreeMap::new() }));
None
},
Some(ref mut n) => {
if key.lt(&n.key) {
match n.lt.insert(key, val) {
None => { self.update_level_size(); return None; }
Some(v) => { return Some(v); }
}
} else if key.gt(&n.key) {
match n.rt.insert(key, val) {
None => { self.update_level_size(); return None; }
Some(v) => { return Some(v); }
}
} else {
let oldval = std::mem::replace(&mut n.val, val); // todo check this
return Some(oldval);
}
}
}
}

/// Insert a nonempty TreeMap into a TreeMap.
@@ -102,7 +231,29 @@ where
/// silently) if this requirement is not met. However if the trees are not overlapping, you
/// must maintain the BST invariant.
fn insert_tree(&mut self, mut other: Self) {
unimplemented!()
match other.inner {
None => { return; },
Some(ref mut on) => {
match self.inner {
None => {
//panic!("self empty!\n");
self.inner = other.inner.take();
},
Some(ref mut n) => {
if on.key.lt(&n.key) {
n.lt.insert_tree(other);
n.lt.update_size();
} else if on.key.gt(&n.key) {
n.rt.insert_tree(other);
n.rt.update_size();
} else {
panic!("Other tree collides with Self!");
}
},
}
}
}
}

/// Remove a key from a TreeMap.
@@ -112,8 +263,35 @@ where
///
/// Hint: take the two child trees of the node you're removing, insert one into the other.
pub fn remove(&mut self, key: K) -> Option<V> {
unimplemented!()
match self.inner {
None => { return None; },
Some(ref mut n) => {
if key.lt(&n.key) {
match n.lt.remove(key) {
None => { None },
Some(x) => {n.lt.update_size(); return Some(x); }
}
} else if key.gt(&n.key) {
match n.rt.remove(key) {
None => { None },
Some(x) => {n.rt.update_size(); return Some(x); }
}
} else {
let oldn = self.inner.take();
if let Some(on) = oldn {
self.insert_tree(on.lt);
self.insert_tree(on.rt);
return Some(on.val);
}
None
// let oldval = std::mem::replace(&mut n.val, None); // todo check this
// let oldlt = std::mem::replace(&mut n.lt, TreeMap{inner:None});
// return Some(oldval);
}
},
}
}
}

/// We will implement a few traits for TreeMap. Starting off: implement the FromIterator trait.
@@ -128,7 +306,11 @@ where
where
T: IntoIterator<Item = (K, V)>,
{
unimplemented!()
let mut tn = TreeMap::new();
for (k, v) in iter {
tn.insert(k, v);
}
return tn;
}
}

@@ -179,7 +361,10 @@ where
type Output = V;

fn index(&self, key: &K) -> &V {
unimplemented!()
match self.get(key) {
None => { panic!("unknown value at index"); },
Some(v) => { return v; }
}
}
}

@@ -189,7 +374,10 @@ where
V: Debug,
{
fn index_mut(&mut self, key: &'a K) -> &mut V {
unimplemented!()
match self.get_mut(key) {
None => { panic!("unknown value at index"); },
Some(v) => { return v; }
}
}
}

@@ -224,8 +412,37 @@ impl<K, V> IntoIter<K, V> {
///
/// Note that this function takes ownership (i.e., tree is passed by value). This is fine,
/// because we are building a *consuming* iterator.
fn new(tree: TreeMap<K, V>) -> Self {
unimplemented!()
fn new(mut tree: TreeMap<K, V>) -> Self {
match tree.inner {
None => { IntoIter {current_val: None, next_nodes: vec![] } },
Some(_) => {
let mut ii = IntoIter { current_val: None, next_nodes: vec![] };
ii.descend_left(tree);
return ii;
}
}
}

// public helper for generating a recursive in-order for the entire tree
fn recursive_descend(&mut self, mut tree: TreeMap<K,V>) -> Vec<Next<(K, V), TreeMap<K, V>>> {
let mut res: Vec<Next<(K, V), TreeMap<K, V>>> = Vec::new();
match tree.inner {
None => {},
Some(_) => {
let oldn = tree.inner.take();
if let Some(on) = oldn {
// right --> self --> left because we are operating on vec instead of stack
//right
res.extend(self.recursive_descend(on.rt));
//self
res.push(Next::Item((on.key, on.val)));
//left
res.extend(self.recursive_descend(on.lt));
}
}
}
res
}

/// This is the main workhorse function for setting up the iterator. In words, this function
@@ -233,8 +450,17 @@ impl<K, V> IntoIter<K, V> {
/// iterator state: the current value, and the next-nodes-to-visit stack. Make sure you add
/// nodes in the right order: we are aiming for an in-order traversal, so the iterator should
/// visit left-child, parent, right-child as we pop things off the stack.
fn descend_left(&mut self, tree: TreeMap<K, V>) {
unimplemented!()
fn descend_left(&mut self, mut tree: TreeMap<K, V>) {
self.next_nodes = self.recursive_descend(tree);
match self.next_nodes.pop() {
None => {self.current_val = None; },
Some(Next::Item((k, v))) => {
// set cur = stack.pop()
self.current_val = Some((k, v));
},
Some(_) => {}
}
// println!("{:?}", self.next_nodes);
}
}

@@ -244,7 +470,7 @@ impl<K, V> IntoIterator for TreeMap<K, V> {
type IntoIter = IntoIter<K, V>;

fn into_iter(self) -> IntoIter<K, V> {
unimplemented!()
return IntoIter::new(self);
}
}

@@ -254,10 +480,28 @@ impl<K, V> IntoIterator for TreeMap<K, V> {
/// value, and then update the nodes to visit.
///
/// Hint: you'll want to use `descend_left`.
/// R: I don't
impl<K, V> Iterator for IntoIter<K, V> {
type Item = (K, V);
fn next(&mut self) -> Option<Self::Item> {
unimplemented!()
match &mut self.current_val {
None => None,
Some(_) => {
let oldval = self.current_val.take();
match self.next_nodes.pop() {
None => {self.current_val = None; },
Some(Next::Item((k, v))) => {
// set cur = stack.pop()
self.current_val = Some((k, v));
},
Some(_) => {}
}
if let Some(on) = oldval {
return Some(on);
}
None
}
}
}
}

@@ -291,6 +535,162 @@ impl<K, V> Iterator for IntoIter<K, V> {
/// annotations and tweaks in a few key places, but your code for the borrowing and mutable
/// iterators should be a nearly exact copy-paste of your code for consuming iterators.


pub struct Iter<'a, K,V> {
next_nodes: Vec<(&'a K, &'a V)>,
current_val: Option<(&'a K, &'a V)>,
}

impl<'a, K,V> Iter<'a, K,V> {
// COPY PASTED from above
fn new(tree: &'a TreeMap<K, V>) -> Self {
match tree.inner {
None => { Iter {current_val: None, next_nodes: vec![] } },
Some(_) => {
let mut ii = Iter { current_val: None, next_nodes: vec![] };
ii.descend_left(&tree);
return ii;
}
}
}

fn recursive_descend(&mut self, tree: &'a TreeMap<K,V>) -> Vec<(&'a K, &'a V)> {
let mut res: Vec<(&'a K, &'a V)> = Vec::new();
match tree.inner {
None => {},
Some(ref on) => {
// right --> self --> left because we are operating on vec instead of stack
//right
res.extend(self.recursive_descend(&on.rt));
//self
res.push((& on.key, & on.val));
//left
res.extend(self.recursive_descend(&on.lt));
}
}
res
}

fn descend_left(&mut self, tree: &'a TreeMap<K, V>) {
self.next_nodes = self.recursive_descend(&tree);
// match self.next_nodes.pop() {
// None => {self.current_val = None; },
// Some((k,v)) => {
// // set cur = stack.pop()
// self.current_val = Some((k, v));
// },
// Some(_) => {}
// }
// println!("{:?}", self.next_nodes);
}

fn next(&mut self) -> Option<(&'a K,&'a V)> {
match self.next_nodes.pop() {
None => {self.current_val = None; },
Some((k,v)) => {
// set cur = stack.pop()
self.current_val = Some((k, v));
},
}
// if let Some(on) = oldval {
// return Some(on);
// }
self.current_val
// match &mut self.current_val {
// None => None,
// Some((k, v)) => {
// //let oldval = self.current_val;//.take();
// }
// }
}
}




pub struct IterMut<'a, K,V> {
next_nodes: Vec<(&'a K, &'a mut V)>,
current_val: Option<(&'a K, &'a mut V)>,
}

impl<'a, K,V> IterMut<'a, K,V> {
// COPY PASTED from above
fn new(tree: &'a mut TreeMap<K, V>) -> Self {
match tree.inner {
None => { IterMut {current_val: None, next_nodes: vec![] } },
Some(_) => {
let mut ii = IterMut { current_val: None, next_nodes: vec![] };
ii.descend_left(tree);
return ii;
}
}
}

fn recursive_descend(&mut self, tree: &'a mut TreeMap<K,V>) -> Vec<(&'a K, &'a mut V)> {
let mut res: Vec<(&'a K, &'a mut V)> = Vec::new();
match tree.inner {
None => {},
Some(ref mut on) => {
// right --> self --> left because we are operating on vec instead of stack
//right
res.extend(self.recursive_descend(&mut on.rt));
//self
res.push((& on.key, &mut on.val));
//left
res.extend(self.recursive_descend(&mut on.lt));
}
}
res
}

fn descend_left(&mut self, tree: &'a mut TreeMap<K, V>) {
self.next_nodes = self.recursive_descend(tree);
// match self.next_nodes.pop() {
// None => {self.current_val = None; },
// Some((k,v)) => {
// // set cur = stack.pop()
// self.current_val = Some((k, v));
// },
// Some(_) => {}
// }
// println!("{:?}", self.next_nodes);
}

fn next(&mut self) -> Option<(&'a K,&'a mut V)> {
match self.next_nodes.pop() {
None => {self.current_val = None; },
Some((k,v)) => {
// set cur = stack.pop()
self.current_val = Some((k, v));
// return Some((k, v));
},
}
// if let Some(on) = oldval {
// return Some(on);
// }
self.current_val.take()
// match &mut self.current_val {
// None => None,
// Some((k, v)) => {
// //let oldval = self.current_val;//.take();
// }
// }
}
}


impl<K,V> TreeMap<K,V> {
pub fn iter_mut(&mut self) -> IterMut<K,V> {
IterMut::new(self)
}

pub fn iter(&self) -> Iter<K,V> {
Iter::new(self)
}
}

/// Part 3: Custom dropping (15)
///
/// The built-in Drop trait behaves poorly because it drops TreeMap recursively. If the TreeMap
@@ -301,7 +701,8 @@ impl<K, V> Iterator for IntoIter<K, V> {
/// root, then drop left, then drop right. Your implementation should maintain this order.
impl<K, V> Drop for TreeMap<K, V> {
fn drop(&mut self) {
unimplemented!()
// unimplemented!()
// give up, out of time
}
}

@@ -471,7 +872,7 @@ mod test {
assert_eq!(iter.next(), None);
}

/* Uncomment when borrowing iterator ready.
#[test]
fn test_borrow_iter() {
let vec = vec![(1, 11), (3, 33), (2, 22)];
@@ -483,9 +884,10 @@ mod test {
assert_eq!(iter.next(), Some((&2, &22)));
assert_eq!(iter.next(), Some((&3, &33)));
assert_eq!(iter.next(), None);
} */
}


/* Uncomment when mutable iterator ready.
/*
#[test]
fn test_mut_iter() {
let vec = vec![(1, 11), (3, 33), (2, 22)];
@@ -501,7 +903,7 @@ mod test {
assert_eq!(tree.get(&1), Some(&101));
assert_eq!(tree.get(&2), Some(&102));
assert_eq!(tree.get(&3), Some(&103));
} */
}*/

use std::cell::RefCell;


Loading…
Cancel
Save