From 1a459e4dc771affbfeb3fdebe60e541f0f385931 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Mon, 30 Oct 2023 17:00:46 -0400 Subject: [PATCH] adding the code --- lectures/18_trees_II/ds_set_lec18_moresoln.h | 155 +++++++++++++++++++ lectures/18_trees_II/ds_set_lec18_starter.h | 129 +++++++++++++++ 2 files changed, 284 insertions(+) create mode 100644 lectures/18_trees_II/ds_set_lec18_moresoln.h create mode 100644 lectures/18_trees_II/ds_set_lec18_starter.h diff --git a/lectures/18_trees_II/ds_set_lec18_moresoln.h b/lectures/18_trees_II/ds_set_lec18_moresoln.h new file mode 100644 index 0000000..f4917b8 --- /dev/null +++ b/lectures/18_trees_II/ds_set_lec18_moresoln.h @@ -0,0 +1,155 @@ +// ------------------------------------------------------------------- +// TREE NODE CLASS +template +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 tree_iterator { +public: + tree_iterator() : ptr_(NULL) {} + tree_iterator(TreeNode* 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 & 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 *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 operator++(int) { tree_iterator temp(*this); ++(*this); return temp; } + tree_iterator & operator--() { /* implementation omitted */ } + tree_iterator operator--(int) { tree_iterator temp(*this); --(*this); return temp; } + +private: + // representation + TreeNode* ptr_; +}; + +// ------------------------------------------------------------------- +// DS_SET CLASS +template +class ds_set { +public: + ds_set() : root_(NULL), size_(0) {} + ds_set(const ds_set& old) : size_(old.size_) { root_ = this->copy_tree(old.root_,NULL); } + ~ds_set() { this->destroy_tree(root_); } + ds_set& operator=(const ds_set& old) { /* implementation omitted */ } + + typedef tree_iterator iterator; + + int size() const { return size_; } + bool operator==(const ds_set& 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& s) { + s.print_in_order(ostr, s.root_); + return ostr; + } + + // ITERATORS + iterator begin() const { + if (!root_) return iterator(NULL); + TreeNode* p = root_; + while (p->left) p = p->left; + return iterator(p); + } + iterator end() const { return iterator(NULL); } + +private: + // REPRESENTATION + TreeNode* root_; + int size_; + + // PRIVATE HELPER FUNCTIONS + TreeNode* copy_tree(TreeNode* old_root) { /* Implemented in Lab 9 */ } + + void destroy_tree(TreeNode* p) { + if (!p) return; + destroy_tree(p->left); + destroy_tree(p->right); + delete p; + } + + /*void destroy_tree(TreeNode* & p) { + // Implemented in Lecture 19 + if (!p) { + p = NULL; + size = 0; + return; + } + + destroy_tree(p->left); + TreeNode* tmp = p->right; + delete p; + destroy_tree(tmp); + } + */ + } + + iterator find(const T& key_value, TreeNode* p) { /* Implemented in Lecture 17 */ } + + std::pair insert(const T& key_value, TreeNode*& p) { + // NOTE: will need revision to support & maintain parent pointers + if (!p) { + p = new TreeNode(key_value); + this->size_++; + return std::pair(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(p), false); + } + + int erase(T const& key_value, TreeNode* &p) { /* Implemented in Lecture 19 */ } + + void print_in_order(std::ostream& ostr, const TreeNode* p) const { + if (p) { + print_in_order(ostr, p->left); + ostr << p->value << "\n"; + print_in_order(ostr, p->right); + } + } +}; diff --git a/lectures/18_trees_II/ds_set_lec18_starter.h b/lectures/18_trees_II/ds_set_lec18_starter.h new file mode 100644 index 0000000..7697339 --- /dev/null +++ b/lectures/18_trees_II/ds_set_lec18_starter.h @@ -0,0 +1,129 @@ +// ------------------------------------------------------------------- +// TREE NODE CLASS +template +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 tree_iterator { +public: + tree_iterator() : ptr_(NULL) {} + tree_iterator(TreeNode* 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; } + // comparions 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 & operator++() { /* discussed & implemented in Lecture 19 */ + + + + + + + + + + return *this; + } + tree_iterator operator++(int) { tree_iterator temp(*this); ++(*this); return temp; } + tree_iterator & operator--() { /* implementation omitted */ } + tree_iterator operator--(int) { tree_iterator temp(*this); --(*this); return temp; } + +private: + // representation + TreeNode* ptr_; +}; + +// ------------------------------------------------------------------- +// DS_SET CLASS +template +class ds_set { +public: + ds_set() : root_(NULL), size_(0) {} + ds_set(const ds_set& old) : size_(old.size_) { root_ = this->copy_tree(old.root_,NULL); } + ~ds_set() { this->destroy_tree(root_); root_ = NULL; } + ds_set& operator=(const ds_set& old) { /* implementation omitted */ } + + typedef tree_iterator iterator; + + int size() const { return size_; } + bool operator==(const ds_set& 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& s) { + s.print_in_order(ostr, s.root_); + return ostr; + } + + // ITERATORS + iterator begin() const { + if (!root_) return iterator(NULL); + TreeNode* p = root_; + while (p->left) p = p->left; + return iterator(p); + } + iterator end() const { return iterator(NULL); } + +private: + // REPRESENTATION + TreeNode* root_; + int size_; + + // PRIVATE HELPER FUNCTIONS + TreeNode* copy_tree(TreeNode* old_root) { /* Implemented in Lab 9 */ } + void destroy_tree(TreeNode* p) { + /* Implemented in Lecture 18 */ + + + + + + } + + iterator find(const T& key_value, TreeNode* p) { /* Implemented in Lecture 17 */ } + + std::pair insert(const T& key_value, TreeNode*& p) { + // NOTE: will need revision to support & maintain parent pointers + if (!p) { + p = new TreeNode(key_value); + this->size_++; + return std::pair(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(p), false); + } + + int erase(T const& key_value, TreeNode* &p) { /* Implemented in Lecture 19 */ } + + void print_in_order(std::ostream& ostr, const TreeNode* p) const { + if (p) { + print_in_order(ostr, p->left); + ostr << p->value << "\n"; + print_in_order(ostr, p->right); + } + } +};