Files
CSCI-1200/lectures/19_trees_II/ds_set_lec18_moresoln.h
2024-03-18 00:44:53 -04:00

156 lines
4.6 KiB
C++

// -------------------------------------------------------------------
// TREE NODE CLASS
template <class T>
class TreeNode {
public:
TreeNode() : left(NULL), right(NULL)/*, parent(NULL)*/ {}
TreeNode(const T& init) : value(init), left(NULL), right(NULL)/*, parent(NULL)*/ {}
T value;
TreeNode* left;
TreeNode* right;
// one way to allow implementation of iterator increment & decrement
// TreeNode* parent;
};
// -------------------------------------------------------------------
// TREE NODE ITERATOR CLASS
template <class T>
class tree_iterator {
public:
tree_iterator() : ptr_(NULL) {}
tree_iterator(TreeNode<T>* p) : ptr_(p) {}
tree_iterator(const tree_iterator& old) : ptr_(old.ptr_) {}
~tree_iterator() {}
tree_iterator& operator=(const tree_iterator& old) { ptr_ = old.ptr_; return *this; }
// operator* gives constant access to the value at the pointer
const T& operator*() const { return ptr_->value; }
// comparison operators are straightforward
bool operator== (const tree_iterator& rgt) { return ptr_ == rgt.ptr_; }
bool operator!= (const tree_iterator& rgt) { return ptr_ != rgt.ptr_; }
// increment & decrement operators
tree_iterator<T> & operator++() { /* discussed & implemented in Lecture 18 */
// if i have right subtree, find left most element of those
if (ptr_->right_ != NULL) {
ptr_ = ptr_->right_;
while (ptr_->left != NULL) {
ptr_ = ptr_->left_;
}
} else {
//TreeNode<T> *tmp = ptr_;
// Keep going up as long as I'm my parent's right child
//while (tmp->value < value ) {
while (ptr_->parent && ptr_->parent_->right == ptr_)
ptr_ = ptr_->parent_;
}
// Go up one more time
ptr_ = ptr_->parent;
}
return *this;
}
tree_iterator<T> operator++(int) { tree_iterator<T> temp(*this); ++(*this); return temp; }
tree_iterator<T> & operator--() { /* implementation omitted */ }
tree_iterator<T> operator--(int) { tree_iterator<T> temp(*this); --(*this); return temp; }
private:
// representation
TreeNode<T>* ptr_;
};
// -------------------------------------------------------------------
// DS_SET CLASS
template <class T>
class ds_set {
public:
ds_set() : root_(NULL), size_(0) {}
ds_set(const ds_set<T>& old) : size_(old.size_) { root_ = this->copy_tree(old.root_,NULL); }
~ds_set() { this->destroy_tree(root_); }
ds_set& operator=(const ds_set<T>& old) { /* implementation omitted */ }
typedef tree_iterator<T> iterator;
int size() const { return size_; }
bool operator==(const ds_set<T>& old) const { return (old.root_ == this->root_); }
// FIND, INSERT & ERASE
iterator find(const T& key_value) { return find(key_value, root_); }
std::pair< iterator, bool > insert(T const& key_value) { return insert(key_value, root_); }
int erase(T const& key_value) { return erase(key_value, root_); }
// OUTPUT & PRINTING
friend std::ostream& operator<< (std::ostream& ostr, const ds_set<T>& s) {
s.print_in_order(ostr, s.root_);
return ostr;
}
// ITERATORS
iterator begin() const {
if (!root_) return iterator(NULL);
TreeNode<T>* p = root_;
while (p->left) p = p->left;
return iterator(p);
}
iterator end() const { return iterator(NULL); }
private:
// REPRESENTATION
TreeNode<T>* root_;
int size_;
// PRIVATE HELPER FUNCTIONS
TreeNode<T>* copy_tree(TreeNode<T>* old_root) { /* Implemented in Lab 9 */ }
void destroy_tree(TreeNode<T>* p) {
if (!p) return;
destroy_tree(p->left);
destroy_tree(p->right);
delete p;
}
/*void destroy_tree(TreeNode<T>* & p) {
// Implemented in Lecture 19
if (!p) {
p = NULL;
size = 0;
return;
}
destroy_tree(p->left);
TreeNode<T>* tmp = p->right;
delete p;
destroy_tree(tmp);
}
*/
}
iterator find(const T& key_value, TreeNode<T>* p) { /* Implemented in Lecture 17 */ }
std::pair<iterator,bool> insert(const T& key_value, TreeNode<T>*& p) {
// NOTE: will need revision to support & maintain parent pointers
if (!p) {
p = new TreeNode<T>(key_value);
this->size_++;
return std::pair<iterator,bool>(iterator(p), true);
}
else if (key_value < p->value)
return insert(key_value, p->left);
else if (key_value > p->value)
return insert(key_value, p->right);
else
return std::pair<iterator,bool>(iterator(p), false);
}
int erase(T const& key_value, TreeNode<T>* &p) { /* Implemented in Lecture 19 */ }
void print_in_order(std::ostream& ostr, const TreeNode<T>* p) const {
if (p) {
print_in_order(ostr, p->left);
ostr << p->value << "\n";
print_in_order(ostr, p->right);
}
}
};