LinkedList.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. /*
  2. ********* Adapted from: *********
  3. https://github.com/ivanseidel/LinkedList
  4. Created by Ivan Seidel Gomes, March, 2013.
  5. Released into the public domain.
  6. *********************************
  7. Changes:
  8. - public access to ListNode (allows for splicing for LRU)
  9. - doubly-linked
  10. - remove caching stuff in favor of standard linked list iterating
  11. - remove sorting
  12. */
  13. #ifndef LinkedList_h
  14. #define LinkedList_h
  15. #include <stddef.h>
  16. template<class T>
  17. struct ListNode {
  18. T data;
  19. ListNode<T> *next;
  20. ListNode<T> *prev;
  21. };
  22. template <typename T>
  23. class LinkedList {
  24. protected:
  25. int _size;
  26. ListNode<T> *root;
  27. ListNode<T> *last;
  28. public:
  29. LinkedList();
  30. ~LinkedList();
  31. /*
  32. Returns current size of LinkedList
  33. */
  34. virtual int size();
  35. /*
  36. Adds a T object in the specified index;
  37. Unlink and link the LinkedList correcly;
  38. Increment _size
  39. */
  40. virtual bool add(int index, T);
  41. /*
  42. Adds a T object in the end of the LinkedList;
  43. Increment _size;
  44. */
  45. virtual bool add(T);
  46. /*
  47. Adds a T object in the start of the LinkedList;
  48. Increment _size;
  49. */
  50. virtual bool unshift(T);
  51. /*
  52. Set the object at index, with T;
  53. Increment _size;
  54. */
  55. virtual bool set(int index, T);
  56. /*
  57. Remove object at index;
  58. If index is not reachable, returns false;
  59. else, decrement _size
  60. */
  61. virtual T remove(int index);
  62. /*
  63. Remove last object;
  64. */
  65. virtual T pop();
  66. /*
  67. Remove first object;
  68. */
  69. virtual T shift();
  70. /*
  71. Get the index'th element on the list;
  72. Return Element if accessible,
  73. else, return false;
  74. */
  75. virtual T get(int index);
  76. /*
  77. Clear the entire array
  78. */
  79. virtual void clear();
  80. ListNode<T>* getNode(int index);
  81. virtual void spliceToFront(ListNode<T>* node);
  82. ListNode<T>* getHead() { return root; }
  83. };
  84. template<typename T>
  85. void LinkedList<T>::spliceToFront(ListNode<T>* node) {
  86. // Node is already root
  87. if (node->prev == NULL) {
  88. return;
  89. }
  90. node->prev->next = node->next;
  91. if (node->next != NULL) {
  92. node->next->prev = node->prev;
  93. }
  94. root->prev = node;
  95. node->next = root;
  96. node->prev = NULL;
  97. root = node;
  98. }
  99. // Initialize LinkedList with false values
  100. template<typename T>
  101. LinkedList<T>::LinkedList()
  102. {
  103. root=NULL;
  104. last=NULL;
  105. _size=0;
  106. }
  107. // Clear Nodes and free Memory
  108. template<typename T>
  109. LinkedList<T>::~LinkedList()
  110. {
  111. ListNode<T>* tmp;
  112. while(root!=NULL)
  113. {
  114. tmp=root;
  115. root=root->next;
  116. delete tmp;
  117. }
  118. last = NULL;
  119. _size=0;
  120. }
  121. /*
  122. Actualy "logic" coding
  123. */
  124. template<typename T>
  125. ListNode<T>* LinkedList<T>::getNode(int index){
  126. int _pos = 0;
  127. ListNode<T>* current = root;
  128. while(_pos < index && current){
  129. current = current->next;
  130. _pos++;
  131. }
  132. return false;
  133. }
  134. template<typename T>
  135. int LinkedList<T>::size(){
  136. return _size;
  137. }
  138. template<typename T>
  139. bool LinkedList<T>::add(int index, T _t){
  140. if(index >= _size)
  141. return add(_t);
  142. if(index == 0)
  143. return unshift(_t);
  144. ListNode<T> *tmp = new ListNode<T>(),
  145. *_prev = getNode(index-1);
  146. tmp->data = _t;
  147. tmp->next = _prev->next;
  148. _prev->next = tmp;
  149. _size++;
  150. return true;
  151. }
  152. template<typename T>
  153. bool LinkedList<T>::add(T _t){
  154. ListNode<T> *tmp = new ListNode<T>();
  155. tmp->data = _t;
  156. tmp->next = NULL;
  157. if(root){
  158. // Already have elements inserted
  159. last->next = tmp;
  160. last = tmp;
  161. }else{
  162. // First element being inserted
  163. root = tmp;
  164. last = tmp;
  165. }
  166. _size++;
  167. return true;
  168. }
  169. template<typename T>
  170. bool LinkedList<T>::unshift(T _t){
  171. if(_size == 0)
  172. return add(_t);
  173. ListNode<T> *tmp = new ListNode<T>();
  174. tmp->next = root;
  175. tmp->data = _t;
  176. root = tmp;
  177. _size++;
  178. return true;
  179. }
  180. template<typename T>
  181. bool LinkedList<T>::set(int index, T _t){
  182. // Check if index position is in bounds
  183. if(index < 0 || index >= _size)
  184. return false;
  185. getNode(index)->data = _t;
  186. return true;
  187. }
  188. template<typename T>
  189. T LinkedList<T>::pop(){
  190. if(_size <= 0)
  191. return T();
  192. if(_size >= 2){
  193. ListNode<T> *tmp = getNode(_size - 2);
  194. T ret = tmp->next->data;
  195. delete(tmp->next);
  196. tmp->next = NULL;
  197. last = tmp;
  198. _size--;
  199. return ret;
  200. }else{
  201. // Only one element left on the list
  202. T ret = root->data;
  203. delete(root);
  204. root = NULL;
  205. last = NULL;
  206. _size = 0;
  207. return ret;
  208. }
  209. }
  210. template<typename T>
  211. T LinkedList<T>::shift(){
  212. if(_size <= 0)
  213. return T();
  214. if(_size > 1){
  215. ListNode<T> *_next = root->next;
  216. T ret = root->data;
  217. delete(root);
  218. root = _next;
  219. _size --;
  220. return ret;
  221. }else{
  222. // Only one left, then pop()
  223. return pop();
  224. }
  225. }
  226. template<typename T>
  227. T LinkedList<T>::remove(int index){
  228. if (index < 0 || index >= _size)
  229. {
  230. return T();
  231. }
  232. if(index == 0)
  233. return shift();
  234. if (index == _size-1)
  235. {
  236. return pop();
  237. }
  238. ListNode<T> *tmp = getNode(index - 1);
  239. ListNode<T> *toDelete = tmp->next;
  240. T ret = toDelete->data;
  241. tmp->next = tmp->next->next;
  242. delete(toDelete);
  243. _size--;
  244. return ret;
  245. }
  246. template<typename T>
  247. T LinkedList<T>::get(int index){
  248. ListNode<T> *tmp = getNode(index);
  249. return (tmp ? tmp->data : T());
  250. }
  251. template<typename T>
  252. void LinkedList<T>::clear(){
  253. while(size() > 0)
  254. shift();
  255. }
  256. #endif