diff --git a/lectures/18_trees_I/ds_set_lec17.h b/lectures/18_trees_I/ds_set_lec17.h deleted file mode 100644 index 66a27f8..0000000 --- a/lectures/18_trees_I/ds_set_lec17.h +++ /dev/null @@ -1,183 +0,0 @@ -// Partial implementation of binary-tree based set class similar to std::set. -// The iterator increment & decrement operations have been omitted. -#ifndef ds_set_h_ -#define ds_set_h_ -#include -#include - -// ------------------------------------------------------------------- -// TREE NODE CLASS -template -class TreeNode { -public: - TreeNode() : left(NULL), right(NULL) {} - TreeNode(const T& init) : value(init), left(NULL), right(NULL) {} - T value; - TreeNode* left; - TreeNode* right; -}; - -// ------------------------------------------------------------------- -// 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_; } - -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_); } - ~ds_set() { - this->destroy_tree(root_); - root_ = NULL; - } - ds_set& operator=(const ds_set& old) { - if (&old != this) { - this->destroy_tree(root_); - root_ = this->copy_tree(old.root_); - size_ = old.size_; - } - return *this; - } - - 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; - } - void print_as_sideways_tree(std::ostream& ostr) const { - print_as_sideways_tree(ostr, root_, 0); - } - - // 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) { - if (old_root == NULL) - return NULL; - TreeNode *answer = new TreeNode(); - answer->value = old_root->value; - answer->left = copy_tree(old_root->left); - answer->right = copy_tree(old_root->right); - return answer; - } - - void destroy_tree(TreeNode* p) { - if (!p) return; - destroy_tree(p->right); - destroy_tree(p->left); - delete p; - } - - iterator find(const T& key_value, TreeNode* p) { - if (!p) return iterator(NULL); - if (p->value > key_value) - return find(key_value, p->left); - else if (p->value < key_value) - return find(key_value, p->right); - else - return iterator(p); - } - - std::pair insert(const T& key_value, TreeNode*& p) { - 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) { - if (!p) return 0; - - // look left & right - if (p->value < key_value) - return erase(key_value, p->right); - else if (p->value > key_value) - return erase(key_value, p->left); - - // Found the node. Let's delete it - assert (p->value == key_value); - if (!p->left && !p->right) { // leaf - delete p; p=NULL; - } else if (!p->left) { // no left child - TreeNode* q = p; p=p->right; delete q; - } else if (!p->right) { // no right child - TreeNode* q = p; p=p->left; delete q; - } else { // Find rightmost node in left subtree - TreeNode* &q = p->left; - while (q->right) q = q->right; - p->value = q->value; - int check = erase(q->value, q); - assert (check == 1); - } - return 1; - } - - 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); - } - } - - void print_as_sideways_tree(std::ostream& ostr, const TreeNode* p, int depth) const { - if (p) { - print_as_sideways_tree(ostr, p->right, depth+1); - for (int i=0; ivalue << "\n"; - print_as_sideways_tree(ostr, p->left, depth+1); - } - } -}; - -#endif diff --git a/lectures/18_trees_I/ds_set_main.cpp b/lectures/18_trees_I/ds_set_main.cpp index f0e75ff..4e09415 100644 --- a/lectures/18_trees_I/ds_set_main.cpp +++ b/lectures/18_trees_I/ds_set_main.cpp @@ -1,28 +1,20 @@ #include #include "ds_set_starter.h" -// #include int main() { // create a set of integers - std::set numbers; + ds_set numbers; // insert some values into the set numbers.insert(10); numbers.insert(5); numbers.insert(20); numbers.insert(15); - numbers.insert(5); // Duplicate value (won't be inserted) - - // print the elements of the set - std::cout << "The elements in the set are:" << std::endl; - for (int num : numbers) { - std::cout << num << " "; - } - std::cout << std::endl; + numbers.insert(5); // duplicate value (won't be inserted) // check if a specific value exists in the set int value = 15; - if (numbers.find(value) != numbers.end()) { + if (numbers.find(value) == true) { std::cout << value << " is found in the set." << std::endl; } else { std::cout << value << " is not found in the set." << std::endl; diff --git a/lectures/18_trees_I/set_main.cpp b/lectures/18_trees_I/set_main.cpp new file mode 100644 index 0000000..bfe0bfd --- /dev/null +++ b/lectures/18_trees_I/set_main.cpp @@ -0,0 +1,31 @@ +#include +#include + +int main() { + // create a set of integers + std::set numbers; + + // insert some values into the set + numbers.insert(10); + numbers.insert(5); + numbers.insert(20); + numbers.insert(15); + numbers.insert(5); // duplicate value (won't be inserted) + + // print the elements of the set + std::cout << "The elements in the set are:" << std::endl; + for (int num : numbers) { + std::cout << num << " "; + } + std::cout << std::endl; + + // check if a specific value exists in the set + int value = 15; + if (numbers.find(value) != numbers.end()) { + std::cout << value << " is found in the set." << std::endl; + } else { + std::cout << value << " is not found in the set." << std::endl; + } + + return 0; +} diff --git a/lectures/19_trees_II/ds_set_lec18_moresoln.h b/lectures/19_trees_II/ds_set_lec18_moresoln.h deleted file mode 100644 index f4917b8..0000000 --- a/lectures/19_trees_II/ds_set_lec18_moresoln.h +++ /dev/null @@ -1,155 +0,0 @@ -// ------------------------------------------------------------------- -// 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/19_trees_II/ds_set_lec18_starter.h b/lectures/19_trees_II/ds_set_lec18_starter.h deleted file mode 100644 index fb274c0..0000000 --- a/lectures/19_trees_II/ds_set_lec18_starter.h +++ /dev/null @@ -1,130 +0,0 @@ -// ------------------------------------------------------------------- -// 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: - //CONSTRUCTORS, DESTRUCTORS, ASSIGNMENT OPERATOR - 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); - } - } -};