4.11 Write an implementation of the set class, with associated iterators using a binary search tree. Add to each node a link to the parent node.
4.12 Write an implementation of the map class by storing a data member of type set<pair<keytype, valuetype> >.
//4.11 bstree.hpp
#ifndef BSTREE_HPP__
#define BSTREE_HPP__
#include <iosfwd>
template< typename Object >
class Set;
const int Null = 0;
template< typename Object >
class BSTree {
private:
class Node {
public:
Node(const Object& val = Object(), Node* l = Null, Node* r = Null,
Node* p = Null) : parent(p), lChild(l),
rChild(r), data(val)
{}
public:
Object data;
Node* lChild;
Node* rChild;
Node* parent;
};
public:
BSTree() : root(Null), parent(Null) {}
~BSTree(){ clear(); }
BSTree(const BSTree& rhs){}
BSTree& operator=(const BSTree& rhs){}
public:
bool contains(const Object& val) const
{ return contains(val, root); }
bool empty() const
{ return root == Null; }
void printTree(std::ostream& out)
{
if(empty())
out << "empty tree/n";
else
printTree(root, out);
}
void clear()
{ clear(root); }
void add(const Object& val)
{ insert(val, root, parent); }
void del(const Object& val)
{ remove(val, root, parent); }
private:
void insert(const Object& val, Node* &t, Node* &parent)
{
if(t == Null)
t = new Node(val, Null, Null, parent);
else if(val < t->data)
insert(val, t->lChild, t);
else if(t->data < val)
insert(val, t->rChild, t);
else
return;
}
void remove(const Object& val, Node* &t, Node* &parent)
{
if(t == Null)
return;
if(val < t->data)
remove(val, t->lChild, t);
else if(t->data < val)
remove(val, t->rChild, t);
else if(t->lChild != Null && t->rChild != Null)
{
t->data = findMin(t->rChild)->data;
remove(t->data, t->rChild, t);
}
else if((t->lChild != Null && t->rChild == Null) ||
(t->lChild == Null && t->rChild != Null))
{
Node* old = t;
t = (t->lChild != Null) ? t->lChild : t->rChild;
t->parent = old->parent;
delete old;
}
else
{
t->parent->rChild == t ? t->parent->rChild = Null :
t->parent->lChild = Null;
delete t;
}
}
bool contains(const Object& val, Node* t) const
{
if(t == Null)
return false;
else if(val < t->data)
return contains(val, t->lChild);
else if(t->data < val)
return contains(val, t->rChild);
else
return true;
}
static Node* findMin(Node* t)
{
if(t != Null)
while(t->lChild != Null)
t = t->lChild;
return t;
}
static Node* findMax(Node* t)
{
if(t != Null)
while(t->rChild != Null)
t = t->rChild;
return t;
}
void clear(Node* &t)
{
if(t != Null)
{
clear(t->lChild);
clear(t->rChild);
delete t;
}
t = Null;
}
void printTree(Node* t, std::ostream& out)
{
if(t != Null)
{
printTree(t->lChild, out);
out << t->data << "/n";
printTree(t->rChild, out);
}
}
private:
Node* root;
Node* parent;
friend class Set<Object>;
};
#endif
//set.hpp
#ifndef SET_HPP__
#define SET_HPP__
#include "bstree.hpp"
template< typename Object >
class Set {
public:
class const_iterator {
public:
const Object& operator*()
{ return current->data; }
const_iterator operator++()
{
if(current->lChild == Null && current->rChild != Null)
return const_iterator(current = BSTree<Object>::findMin(current->rChild));
else if(current->lChild == Null && current->rChild == Null
&& current->parent->rChild == current)
return const_iterator(current = current->parent->parent);
else if(current->lChild == Null && current->rChild == Null
&& current->parent->lChild == current)
return const_iterator(current = current->parent);
else if(current->lChild != Null && current->rChild != Null)
return const_iterator(current = BSTree<Object>::findMin(current->rChild));
else if(current->lChild != Null && current->rChild == Null
&& current->parent->lChild == current)
return const_iterator(current = current->parent);
else
return const_iterator(current = current->rChild);
}
const_iterator operator++(int)
{
const_iterator old = *this;
++(*this);
return old;
}
bool operator==(const const_iterator& rhs) const
{ return current == rhs.current; }
bool operator!=(const const_iterator& rhs) const
{ return !(*this == rhs); }
protected:
const_iterator(typename BSTree<Object>::Node* p) : current(p) {}
typename BSTree<Object>::Node* current;
friend class Set<Object>;
};
public:
Set() : tree(new BSTree<Object>()){}
~Set()
{
delete tree;
}
const_iterator begin() const
{
return const_iterator(BSTree<Object>::findMin(tree->root));
}
const_iterator end() const
{
return const_iterator(BSTree<Object>::findMax(tree->root));
}
bool empty() const
{ return tree->empty(); }
void insert(const Object& val)
{
tree->add(val);
}
int erase(const Object& val)
{
if(!tree->contains(val))
return 0;
tree->del(val);
return 1;
}
bool insert(const Object& val, const_iterator it) const
{
if(tree->contains(val))
return false;
tree->insert(val, it.current, it.current->parent);
return true;
}
const_iterator erase(const_iterator it)
{
const_iterator old = it;
++old;
erase(it.current->data);
return old;
}
const_iterator erase(const_iterator start, const_iterator end)
{
while(start != end)
erase(start++);
return end;
}
void print(std::ostream& out)
{ tree->printTree(out); }
private:
BSTree<Object>* tree;
};
#endif
//4.12 map.hpp
#ifndef MAP_HPP__
#define MAP_HPP__
#include <set>
template< typename KeyType, typename ValueType >
class Map {
public:
class iterator {
public:
iterator() : it(0){}
ValueType& operator*()
{ return it.operator*().second; }
iterator operator++()
{ return it.operator++(); }
iterator operator++(int)
{ return it.operator++(int); }
iterator operator--()
{ return it.operator--(); }
iterator operator--(int)
{ return it.operator--(int); }
bool operator==(const iterator& rhs)
{ return it == rhs.it; }
bool operator!=(const iterator& rhs)
{ return !(*this == rhs); }
std::pair<KeyType, ValueType>* operator->()
{ return &(*it); }
private:
iterator(typename std::set< std::pair< KeyType, ValueType > >::iterator& i)
: it(i) {}
typename std::set< std::pair< KeyType, ValueType > >::iterator it;
friend class Map<KeyType, ValueType>;
};
public:
Map() : store(new std::set<std::pair<KeyType, ValueType> >())
{}
~Map() { delete store; }
iterator begin() const { return store->begin(); }
iterator end() const { return store->end(); }
size_t size() const { return store->size(); }
bool empty() const { return store->empty(); }
ValueType& operator[](const KeyType& key)
{
iterator it = iterator(store->begin());
while(it != store->end())
{
if(it->first == key)
return *it;
++it;
}
insert(key);
return *(--it);
}
void insert(const KeyType& key, const ValueType& val = ValueType())
{ store->insert(std::pair<KeyType, ValueType>(key, val)); }
iterator insert(const iterator& it, const std::pair<KeyType, ValueType>& val)
{ return iterator(store->insert(it.it,val)); }
iterator find(const KeyType& key)
{
iterator it = store->begin();
while(it != store->end())
{
if(*it == key)
return it;
++it;
}
return it;
}
iterator erase(const iterator& it)
{ return iterator(store->erase(it.it)); }
iterator erase(const iterator& start, const iterator& end)
{ return iterator(store->erase(start.it, end.it)); }
private:
std::set<std::pair<KeyType, ValueType> >* store;
};
#endif