Advertisement
Cinestra

Project 2 before trying to perfect

Mar 1st, 2023
25
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.17 KB | None | 0 0
  1. #include "Set.h"
  2. #include <iostream>
  3.  
  4. void Set::initializeEmptySet()
  5. {
  6. m_size = 0;
  7.  
  8. m_head = new Node;
  9. m_tail = m_head;
  10. m_head->m_next = nullptr;
  11. m_head->m_prev = nullptr;
  12. }
  13.  
  14. Set::Set()
  15. {
  16. initializeEmptySet();
  17. }
  18.  
  19. // Before we can actually insert the node, we need to implement the insert before function
  20. void Set::insertNewHead(const ItemType& value)
  21. {
  22. Node* new_head = new Node;
  23. new_head->m_value = value;
  24.  
  25. m_head->m_prev = new_head;
  26. new_head->m_prev = nullptr;
  27. new_head->m_next = m_head;
  28. m_head = new_head;
  29.  
  30. m_size++;
  31. }
  32.  
  33. void Set::insertNewTail(const ItemType& value)
  34. {
  35. if (m_head == nullptr)
  36. insertNewHead(value);
  37.  
  38. else
  39. {
  40. Node* traversal_node = m_head;
  41. while (traversal_node->m_next != nullptr)
  42. {
  43. traversal_node = traversal_node->m_next;
  44. }
  45.  
  46. Node* new_tail = new Node;
  47. traversal_node->m_next = new_tail;
  48. new_tail->m_value = value;
  49. new_tail->m_prev = traversal_node;
  50. new_tail->m_next = nullptr;
  51. m_tail = new_tail;
  52. }
  53.  
  54. m_size++;
  55. }
  56.  
  57. void Set::insertBefore(Node* p, const ItemType& value)
  58. {
  59. //Create a new node
  60.  
  61. Node* new_pointer = new Node;
  62. new_pointer->m_value = value;
  63.  
  64. if (p == m_head)
  65. {
  66. insertNewHead(value);
  67. return;
  68. }
  69.  
  70. // Set the new pointer's previous pointer equal to p's previous pointer
  71. // Then set the new pointer's next pointer equal to p
  72. new_pointer->m_prev = p->m_prev;
  73. new_pointer->m_next = p;
  74.  
  75. // We must now make the previous nodes point to this new node
  76. // Then we must make the next node have its previous point to this node.
  77. new_pointer->m_prev->m_next = new_pointer;
  78. new_pointer->m_next->m_prev = new_pointer;
  79.  
  80. m_size++;
  81. }
  82.  
  83. // I have no idea how to write these function parameters
  84. // Why is there a Set:: before declaring a node pointer?
  85. // Is it because we can only define what a node pointer is after defining it's from the Set class?
  86. Set::Node* Set::findClosestLocation(const ItemType& value) const
  87. {
  88. Node* p = m_head;
  89.  
  90. while (p->m_next != nullptr && p->m_value < value)
  91. {
  92. p = p->m_next;
  93. }
  94.  
  95. return p;
  96. }
  97.  
  98. bool Set::insert(const ItemType& value)
  99. {
  100. Node* closestNode = findClosestLocation(value);
  101.  
  102. // When we are inserting a new head into an empty linkedList we should also initialize the tail.
  103. if (m_size == 0)
  104. {
  105. insertNewHead(value);
  106. m_tail = m_head;
  107. return true;
  108. }
  109.  
  110. // First check if we already have that value in our linked list
  111. else if (closestNode->m_value == value)
  112. {
  113. return false;
  114. }
  115.  
  116. // Then if it's closest node is the tail, we'll check if it should go before or after the tail
  117. // If we need to create a new tail, then we'll run that function
  118. // If not, we can actually just insert it before the tail (and run it like everything else)
  119. else if (closestNode == m_tail)
  120. {
  121. if (closestNode->m_value > m_tail->m_value)
  122. {
  123. insertNewTail(value);
  124. return true;
  125. }
  126. }
  127.  
  128. // insertBefore command actually checks if it should be a new head
  129. insertBefore(closestNode, value);
  130. return true;
  131. }
  132.  
  133. void Set::actualErase(Node* p)
  134. {
  135. if (m_size == 1)
  136. {
  137. p->m_next = p->m_prev = nullptr;
  138. }
  139.  
  140. else if (p == m_head)
  141. {
  142. m_head = m_head->m_next;
  143. p->m_next->m_prev = nullptr;
  144. }
  145.  
  146. else if (p == m_tail)
  147. {
  148. m_tail = m_tail->m_prev;
  149. p->m_prev->m_next = nullptr;
  150. }
  151.  
  152. else
  153. {
  154. p->m_prev->m_next = p->m_next;
  155. p->m_next->m_prev = p->m_prev;
  156. }
  157.  
  158. delete p;
  159. m_size--;
  160. }
  161.  
  162. bool Set::erase(const ItemType& value)
  163. {
  164. Node* closestNode = findClosestLocation(value);
  165.  
  166. if (closestNode->m_value != value)
  167. return false;
  168.  
  169. actualErase(closestNode);
  170. return true;
  171. }
  172.  
  173. Set::~Set()
  174. {
  175. while (m_size > 1)
  176. {
  177. actualErase(m_head->m_next);
  178. }
  179.  
  180. delete m_head;
  181. }
  182.  
  183. void Set::printLinkedList()
  184. {
  185. Node* traversalNode = m_head;
  186.  
  187. while (traversalNode != nullptr)
  188. {
  189. std::cout << traversalNode->m_value << " ";
  190. traversalNode = traversalNode->m_next;
  191. }
  192.  
  193. std::cout << "\n";
  194. }
  195.  
  196. bool Set::contains(const ItemType& value) const
  197. {
  198. Node* closestNode = findClosestLocation(value);
  199. return (closestNode->m_value == value);
  200. }
  201.  
  202. bool Set::get(int i, ItemType& value) const
  203. {
  204. if (i < 0 || i >= m_size)
  205. return false;
  206.  
  207. Node* traversalNode;
  208.  
  209. // Closer to head
  210. if (i < (m_size / 2))
  211. {
  212. traversalNode = m_head;
  213. for (int j = 0; j != i; j++)
  214. {
  215. traversalNode = traversalNode->m_next;
  216. }
  217. }
  218.  
  219. // Closer to tail
  220. else
  221. {
  222. traversalNode = m_tail;
  223. for (int j = m_size - 1; j != i; j--)
  224. {
  225. traversalNode = traversalNode->m_prev;
  226. }
  227. }
  228.  
  229. value = traversalNode->m_value;
  230. return true;
  231. }
  232.  
  233. void Set::swap(Set& other)
  234. {
  235. Node* tempHead = other.m_head;
  236. other.m_head = m_head;
  237. m_head = tempHead;
  238.  
  239. int tempSize = other.m_size;
  240. other.m_size = m_size;
  241. m_size = tempSize;
  242.  
  243. // Ask Carey later about swapping tails
  244. // It makes sense that you can't really swap the tails after swapping the heads
  245. // Is there a more elegant solution though?
  246.  
  247. Node* originalTraversalNode = m_head;
  248.  
  249. for (int i = 1; i < m_size; i++)
  250. {
  251. originalTraversalNode = originalTraversalNode->m_next;
  252. }
  253.  
  254. m_tail = originalTraversalNode;
  255.  
  256. Node* swappedTraversalNode = other.m_head;
  257.  
  258. for (int i = 1; i < other.m_size; i++)
  259. {
  260. swappedTraversalNode = swappedTraversalNode->m_next;
  261. }
  262.  
  263. other.m_tail = swappedTraversalNode;
  264. }
  265.  
  266. Set::Set(const Set& other)
  267. {
  268. initializeEmptySet();
  269.  
  270. // Copy all non-dummy other Nodes. (This will set m_size.)
  271. // Inserting each new node before the dummy node that m_head points to
  272. // puts the new node at the end of the list.
  273.  
  274. Node* traversalNode = other.m_head;
  275.  
  276. for (int i = 1; i < other.m_size; i++)
  277. {
  278. insert(traversalNode->m_value);
  279. traversalNode = traversalNode->m_next;
  280. }
  281. }
  282.  
  283. Set& Set::operator=(const Set& other)
  284. {
  285. // Trying to avoid aliasing, which is when we use two different pointers/ references to acess the same variable
  286. // This is a problem if we try to first delete the data of the original before reassigning it to itself
  287. // Our solution it see if the parameter has the same object address as the target object
  288. if (this == &other)
  289. {
  290. return *this;
  291. }
  292.  
  293. // Typically, we could simply delete the elements inside the array now, but Carey doesn't want us to use a for loop
  294. // Thus, we will do the Smallberg method of using a copy constructor and a swap method
  295.  
  296. // Call the copy constructor to recreate the other set and then swap elements between the original set and the copied set
  297. // Temporary array will actually deconstruct itself
  298. Set temp(other);
  299. swap(temp);
  300.  
  301. Node* traversalNode = m_head;
  302. int i = 1;
  303.  
  304. std::cout << "\n";
  305.  
  306. // Return the dereferenced contents of the Sets
  307. // Now works for a = b = c as well
  308. return *this;
  309. }
  310.  
  311. void unite(const Set& s1, const Set& s2, Set& result)
  312. {
  313. // We have to worry about aliasing, which is when we use two different pointers/ references to acess the same variable
  314. // The big worry here is if inputted result is actually s1 or s2
  315.  
  316. // If s1, s2, and result are all the same-- then the result is already the union
  317. // If the result is s1, insert s2's elements into the result
  318. // If the result is s2, insert s1's elements into the result
  319. // If the result is its own distinct set, we will first assign it s1's contents, then check if s2 is the same as s1, and if they are different then we will insert s2 into s1
  320.  
  321. // Naturally we will try to insert S2 into S1
  322. const Set* insertedNode = &s2;
  323.  
  324. // First let's check if s1, s2, and result are all the same
  325. if (&result == &s1 && &result == &s2)
  326. {
  327. return;
  328. }
  329.  
  330. // If result is the same as S2, we will make the insertedNode into s1
  331. else if (&result == &s2)
  332. insertedNode == &s1;
  333.  
  334. // Now that we have determined that result is not s2 and that s1, s2, and result are not all the same
  335. // We will assign result to be equal to s1
  336. // Then we will check if s1 and s2 are the same
  337. // If they are, then we will simply return the set
  338. else
  339. {
  340. result = s1;
  341. if (&s1 == &s2)
  342. {
  343. return;
  344. }
  345. }
  346.  
  347. // If s1 and s2 are not the same, then we will insert one into the other
  348. // If result was the same address as s2, then we will
  349.  
  350. int size_of_insertedNode = insertedNode->size();
  351. ItemType x;
  352.  
  353. for (int i = 0; i < size_of_insertedNode; i++)
  354. {
  355. insertedNode->get(i, x);
  356. result.insert(x);
  357. }
  358. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement