Advertisement
Cinestra

Incorrect circular linked list

Mar 17th, 2023
20
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.61 KB | None | 0 0
  1. #include "Mapper.h"
  2.  
  3. void Mapper::initializeEmptyMapper()
  4. {
  5. m_size = 0;
  6.  
  7. m_dummy = new Node;
  8. m_dummy->m_next = m_dummy;
  9. m_dummy->m_prev = m_dummy;
  10. }
  11.  
  12. Mapper::Mapper()
  13. {
  14. initializeEmptyMapper();
  15. }
  16.  
  17. // Before we can actually insert the node, we need to implement the insert before function
  18. void Mapper::insertNewHead(const std::string& name, const std::string& association)
  19. {
  20.  
  21. Node* new_head = new Node;
  22. new_head->m_name = name;
  23. new_head->m_association = association;
  24.  
  25. if (m_head == nullptr)
  26. {
  27. m_head = new_head;
  28. m_head->m_next = m_dummy;
  29. m_head->m_prev = m_dummy;
  30. m_tail = m_head;
  31.  
  32. m_size++;
  33.  
  34. m_dummy->m_next = m_head;
  35. m_dummy->m_prev = m_head;
  36.  
  37. return;
  38. }
  39.  
  40. m_head->m_prev = new_head;
  41. new_head->m_prev = m_dummy;
  42. new_head->m_next = m_head;
  43. m_head = new_head;
  44.  
  45. m_size++;
  46.  
  47. m_dummy->m_next = m_head;
  48. }
  49.  
  50. void Mapper::insertNewTail(const std::string& name, const std::string& association)
  51. {
  52. Node* new_tail = new Node;
  53. m_tail->m_next = new_tail;
  54. new_tail->m_name = name;
  55. new_tail->m_association = association;
  56. new_tail->m_prev = m_tail;
  57. new_tail->m_next = m_dummy;
  58. m_tail = new_tail;
  59.  
  60. m_size++;
  61.  
  62. m_dummy->m_prev = m_tail;
  63. }
  64.  
  65. void Mapper::insertBefore(Node* p, const std::string& name, const std::string& association)
  66. {
  67. //Create a new node
  68.  
  69. Node* new_pointer = new Node;
  70. new_pointer->m_name = name;
  71. new_pointer->m_association = association;
  72.  
  73. if (p == m_head)
  74. {
  75. insertNewHead(name, association);
  76. return;
  77. }
  78.  
  79. // Set the new pointer's previous pointer equal to p's previous pointer
  80. // Then set the new pointer's next pointer equal to p
  81. new_pointer->m_prev = p->m_prev;
  82. new_pointer->m_next = p;
  83.  
  84. // We must now make the previous nodes point to this new node
  85. // Then we must make the next node have its previous point to this node.
  86. new_pointer->m_prev->m_next = new_pointer;
  87. new_pointer->m_next->m_prev = new_pointer;
  88.  
  89. m_size++;
  90. }
  91.  
  92. Mapper::Node* Mapper::findClosestLocation(const std::string& name) const
  93. {
  94. // Have to change this implementation because we always start with a dummy node
  95.  
  96. if (m_size == 0)
  97. {
  98. return m_dummy;
  99. }
  100.  
  101. Node* traversalNode = m_head;
  102.  
  103. while (traversalNode->m_next != m_dummy && traversalNode->m_name < name)
  104. traversalNode = traversalNode->m_next;
  105.  
  106. return traversalNode;
  107. }
  108.  
  109. void Mapper::associate(const std::string& key, const std::string& value)
  110. {
  111. if (m_head == nullptr)
  112. {
  113. insertNewHead(key, value);
  114. return;
  115. }
  116.  
  117. Node* closestNode = findClosestLocation(key);
  118.  
  119. if (closestNode->m_name == key)
  120. {
  121. // It doesn't really matter if the associated value before was the same or not
  122. // We'll ensure that the latest associated value is always updated
  123. closestNode->m_association = value;
  124. return;
  125. }
  126.  
  127. else if (closestNode == m_tail)
  128. {
  129. if (key > m_tail->m_name)
  130. {
  131. insertNewTail(key, value);
  132. return;
  133. }
  134. }
  135.  
  136. // insertBefore command actually checks if it should be a new head
  137. insertBefore(closestNode, key, value);
  138. }
  139.  
  140. void Mapper::actualErase(Node* p)
  141. {
  142. // There are 4 cases to consider
  143. // If there is only a single node, then we will delete it and set its next and prev to nullptr
  144. // This is different from deleting a node in the middle because we don't have to link surrounding nodes together after deletion
  145. if (m_size == 1)
  146. {
  147. p->m_next = p->m_prev = nullptr;
  148. m_head = nullptr;
  149. m_tail = nullptr;
  150. }
  151.  
  152. // If we are deleting the head, then we must allocate a new head
  153. else if (p == m_head)
  154. {
  155. m_head = m_head->m_next;
  156. m_dummy->m_next = m_head;
  157. m_head->m_prev = m_dummy;
  158. }
  159.  
  160. // If we are deleting the tail, then we must allocate a new tail
  161. else if (p == m_tail)
  162. {
  163. m_tail = m_tail->m_prev;
  164. m_dummy->m_prev = m_tail;
  165. m_tail->m_next = m_dummy;
  166. }
  167.  
  168. // Because we are deleting a node in the middle, we need to make sure that we are linking the surrounding nodes together
  169. else
  170. {
  171. p->m_prev->m_next = p->m_next;
  172. p->m_next->m_prev = p->m_prev;
  173. }
  174.  
  175. delete p;
  176. m_size--;
  177. }
  178.  
  179. void Mapper::erase(const std::string& key)
  180. {
  181. if (m_size == 0)
  182. return;
  183.  
  184. Node* closestNode = findClosestLocation(key);
  185.  
  186. if (closestNode->m_name != key)
  187. return;
  188.  
  189. actualErase(closestNode);
  190. }
  191.  
  192. bool Mapper::empty() const
  193. {
  194. return (m_size == 0);
  195. }
  196.  
  197. Mapper::~Mapper()
  198. {
  199. while (m_size > 0)
  200. {
  201. actualErase(m_head);
  202. }
  203.  
  204. delete m_dummy;
  205. }
  206.  
  207. bool Mapper::find(const std::string& key, std::string& value) const
  208. {
  209. if (m_size == 0)
  210. return false;
  211.  
  212. Node* closestNode = findClosestLocation(key);
  213.  
  214. if (closestNode->m_name == key)
  215. {
  216. value = closestNode->m_association;
  217. return true;
  218. }
  219.  
  220. else
  221. return false;
  222. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement