| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- /*
- ********* Adapted from: *********
- https://github.com/ivanseidel/LinkedList
- Created by Ivan Seidel Gomes, March, 2013.
- Released into the public domain.
- *********************************
- Changes:
- - public access to ListNode (allows for splicing for LRU)
- - doubly-linked
- - remove caching stuff in favor of standard linked list iterating
- - remove sorting
- */
- #ifndef LinkedList_h
- #define LinkedList_h
- #include <stddef.h>
- template<class T>
- struct ListNode {
- T data;
- ListNode<T> *next;
- ListNode<T> *prev;
- };
- template <typename T>
- class LinkedList {
- protected:
- size_t _size;
- ListNode<T> *root;
- ListNode<T> *last;
- public:
- LinkedList();
- ~LinkedList();
- /*
- Returns current size of LinkedList
- */
- virtual size_t size() const;
- /*
- Adds a T object in the specified index;
- Unlink and link the LinkedList correcly;
- Increment _size
- */
- virtual bool add(int index, T);
- /*
- Adds a T object in the end of the LinkedList;
- Increment _size;
- */
- virtual bool add(T);
- /*
- Adds a T object in the start of the LinkedList;
- Increment _size;
- */
- virtual bool unshift(T);
- /*
- Set the object at index, with T;
- Increment _size;
- */
- virtual bool set(int index, T);
- /*
- Remove object at index;
- If index is not reachable, returns false;
- else, decrement _size
- */
- virtual T remove(int index);
- /*
- Remove last object;
- */
- virtual T pop();
- /*
- Remove first object;
- */
- virtual T shift();
- /*
- Get the index'th element on the list;
- Return Element if accessible,
- else, return false;
- */
- virtual T get(int index);
- /*
- Clear the entire array
- */
- virtual void clear();
- ListNode<T>* getNode(int index);
- virtual void spliceToFront(ListNode<T>* node);
- ListNode<T>* getHead() { return root; }
- T getLast() const { return last == NULL ? T() : last->data; }
- };
- template<typename T>
- void LinkedList<T>::spliceToFront(ListNode<T>* node) {
- // Node is already root
- if (node->prev == NULL) {
- return;
- }
- node->prev->next = node->next;
- if (node->next != NULL) {
- node->next->prev = node->prev;
- } else {
- last = node->prev;
- }
- root->prev = node;
- node->next = root;
- node->prev = NULL;
- root = node;
- }
- // Initialize LinkedList with false values
- template<typename T>
- LinkedList<T>::LinkedList()
- {
- root=NULL;
- last=NULL;
- _size=0;
- }
- // Clear Nodes and free Memory
- template<typename T>
- LinkedList<T>::~LinkedList()
- {
- ListNode<T>* tmp;
- while(root!=NULL)
- {
- tmp=root;
- root=root->next;
- delete tmp;
- }
- last = NULL;
- _size=0;
- }
- /*
- Actualy "logic" coding
- */
- template<typename T>
- ListNode<T>* LinkedList<T>::getNode(int index){
- int _pos = 0;
- ListNode<T>* current = root;
- while(_pos < index && current){
- current = current->next;
- _pos++;
- }
- return false;
- }
- template<typename T>
- size_t LinkedList<T>::size() const{
- return _size;
- }
- template<typename T>
- bool LinkedList<T>::add(int index, T _t){
- if(index >= _size)
- return add(_t);
- if(index == 0)
- return unshift(_t);
- ListNode<T> *tmp = new ListNode<T>(),
- *_prev = getNode(index-1);
- tmp->data = _t;
- tmp->next = _prev->next;
- _prev->next = tmp;
- _size++;
- return true;
- }
- template<typename T>
- bool LinkedList<T>::add(T _t){
- ListNode<T> *tmp = new ListNode<T>();
- tmp->data = _t;
- tmp->next = NULL;
- if(root){
- // Already have elements inserted
- last->next = tmp;
- last = tmp;
- }else{
- // First element being inserted
- root = tmp;
- last = tmp;
- }
- _size++;
- return true;
- }
- template<typename T>
- bool LinkedList<T>::unshift(T _t){
- if(_size == 0)
- return add(_t);
- ListNode<T> *tmp = new ListNode<T>();
- tmp->next = root;
- root->prev = tmp;
- tmp->data = _t;
- root = tmp;
- _size++;
- return true;
- }
- template<typename T>
- bool LinkedList<T>::set(int index, T _t){
- // Check if index position is in bounds
- if(index < 0 || index >= _size)
- return false;
- getNode(index)->data = _t;
- return true;
- }
- template<typename T>
- T LinkedList<T>::pop(){
- if(_size <= 0)
- return T();
- if(_size >= 2){
- ListNode<T> *tmp = last->prev;
- T ret = tmp->next->data;
- delete(tmp->next);
- tmp->next = NULL;
- last = tmp;
- _size--;
- return ret;
- }else{
- // Only one element left on the list
- T ret = root->data;
- delete(root);
- root = NULL;
- last = NULL;
- _size = 0;
- return ret;
- }
- }
- template<typename T>
- T LinkedList<T>::shift(){
- if(_size <= 0)
- return T();
- if(_size > 1){
- ListNode<T> *_next = root->next;
- T ret = root->data;
- delete(root);
- root = _next;
- _size --;
- return ret;
- }else{
- // Only one left, then pop()
- return pop();
- }
- }
- template<typename T>
- T LinkedList<T>::remove(int index){
- if (index < 0 || index >= _size)
- {
- return T();
- }
- if(index == 0)
- return shift();
- if (index == _size-1)
- {
- return pop();
- }
- ListNode<T> *tmp = getNode(index - 1);
- ListNode<T> *toDelete = tmp->next;
- T ret = toDelete->data;
- tmp->next = tmp->next->next;
- delete(toDelete);
- _size--;
- return ret;
- }
- template<typename T>
- T LinkedList<T>::get(int index){
- ListNode<T> *tmp = getNode(index);
- return (tmp ? tmp->data : T());
- }
- template<typename T>
- void LinkedList<T>::clear(){
- while(size() > 0)
- shift();
- }
- #endif
|