|
|
@@ -1,8 +1,8 @@
|
|
|
/*
|
|
|
********* Adapted from: *********
|
|
|
- https://github.com/ivanseidel/LinkedList
|
|
|
- Created by Ivan Seidel Gomes, March, 2013.
|
|
|
- Released into the public domain.
|
|
|
+ https://github.com/ivanseidel/LinkedList
|
|
|
+ Created by Ivan Seidel Gomes, March, 2013.
|
|
|
+ Released into the public domain.
|
|
|
*********************************
|
|
|
|
|
|
Changes:
|
|
|
@@ -12,7 +12,6 @@
|
|
|
- remove sorting
|
|
|
*/
|
|
|
|
|
|
-
|
|
|
#ifndef LinkedList_h
|
|
|
#define LinkedList_h
|
|
|
|
|
|
@@ -20,78 +19,78 @@
|
|
|
|
|
|
template<class T>
|
|
|
struct ListNode {
|
|
|
- T data;
|
|
|
- ListNode<T> *next;
|
|
|
- ListNode<T> *prev;
|
|
|
+ T data;
|
|
|
+ ListNode<T> *next;
|
|
|
+ ListNode<T> *prev;
|
|
|
};
|
|
|
|
|
|
template <typename T>
|
|
|
class LinkedList {
|
|
|
|
|
|
protected:
|
|
|
- int _size;
|
|
|
- ListNode<T> *root;
|
|
|
- ListNode<T> *last;
|
|
|
+ int _size;
|
|
|
+ ListNode<T> *root;
|
|
|
+ ListNode<T> *last;
|
|
|
|
|
|
public:
|
|
|
- LinkedList();
|
|
|
- ~LinkedList();
|
|
|
-
|
|
|
- /*
|
|
|
- Returns current size of LinkedList
|
|
|
- */
|
|
|
- virtual int 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);
|
|
|
+ LinkedList();
|
|
|
+ ~LinkedList();
|
|
|
+
|
|
|
+ /*
|
|
|
+ Returns current size of LinkedList
|
|
|
+ */
|
|
|
+ virtual int 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; }
|
|
|
+ T getLast() const { return last == NULL ? T() : last->data; }
|
|
|
|
|
|
};
|
|
|
|
|
|
@@ -106,6 +105,8 @@ void LinkedList<T>::spliceToFront(ListNode<T>* node) {
|
|
|
node->prev->next = node->next;
|
|
|
if (node->next != NULL) {
|
|
|
node->next->prev = node->prev;
|
|
|
+ } else {
|
|
|
+ last = node->prev;
|
|
|
}
|
|
|
|
|
|
root->prev = node;
|
|
|
@@ -118,197 +119,198 @@ void LinkedList<T>::spliceToFront(ListNode<T>* node) {
|
|
|
template<typename T>
|
|
|
LinkedList<T>::LinkedList()
|
|
|
{
|
|
|
- root=NULL;
|
|
|
- last=NULL;
|
|
|
- _size=0;
|
|
|
+ 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;
|
|
|
+ ListNode<T>* tmp;
|
|
|
+ while(root!=NULL)
|
|
|
+ {
|
|
|
+ tmp=root;
|
|
|
+ root=root->next;
|
|
|
+ delete tmp;
|
|
|
+ }
|
|
|
+ last = NULL;
|
|
|
+ _size=0;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- Actualy "logic" coding
|
|
|
+ Actualy "logic" coding
|
|
|
*/
|
|
|
|
|
|
template<typename T>
|
|
|
ListNode<T>* LinkedList<T>::getNode(int index){
|
|
|
|
|
|
- int _pos = 0;
|
|
|
- ListNode<T>* current = root;
|
|
|
+ int _pos = 0;
|
|
|
+ ListNode<T>* current = root;
|
|
|
|
|
|
- while(_pos < index && current){
|
|
|
- current = current->next;
|
|
|
+ while(_pos < index && current){
|
|
|
+ current = current->next;
|
|
|
|
|
|
- _pos++;
|
|
|
- }
|
|
|
+ _pos++;
|
|
|
+ }
|
|
|
|
|
|
- return false;
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
int LinkedList<T>::size() const{
|
|
|
- return _size;
|
|
|
+ return _size;
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
bool LinkedList<T>::add(int index, T _t){
|
|
|
|
|
|
- if(index >= _size)
|
|
|
- return add(_t);
|
|
|
+ if(index >= _size)
|
|
|
+ return add(_t);
|
|
|
|
|
|
- if(index == 0)
|
|
|
- return unshift(_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;
|
|
|
+ ListNode<T> *tmp = new ListNode<T>(),
|
|
|
+ *_prev = getNode(index-1);
|
|
|
+ tmp->data = _t;
|
|
|
+ tmp->next = _prev->next;
|
|
|
+ _prev->next = tmp;
|
|
|
|
|
|
- _size++;
|
|
|
+ _size++;
|
|
|
|
|
|
- return true;
|
|
|
+ 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;
|
|
|
- }
|
|
|
+ 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++;
|
|
|
+ _size++;
|
|
|
|
|
|
- return true;
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
bool LinkedList<T>::unshift(T _t){
|
|
|
|
|
|
- if(_size == 0)
|
|
|
- return add(_t);
|
|
|
+ if(_size == 0)
|
|
|
+ return add(_t);
|
|
|
|
|
|
- ListNode<T> *tmp = new ListNode<T>();
|
|
|
- tmp->next = root;
|
|
|
- tmp->data = _t;
|
|
|
- root = tmp;
|
|
|
+ ListNode<T> *tmp = new ListNode<T>();
|
|
|
+ tmp->next = root;
|
|
|
+ root->prev = tmp;
|
|
|
+ tmp->data = _t;
|
|
|
+ root = tmp;
|
|
|
|
|
|
- _size++;
|
|
|
+ _size++;
|
|
|
|
|
|
- return true;
|
|
|
+ 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;
|
|
|
+ // Check if index position is in bounds
|
|
|
+ if(index < 0 || index >= _size)
|
|
|
+ return false;
|
|
|
|
|
|
- getNode(index)->data = _t;
|
|
|
- return true;
|
|
|
+ getNode(index)->data = _t;
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
T LinkedList<T>::pop(){
|
|
|
- if(_size <= 0)
|
|
|
- return T();
|
|
|
-
|
|
|
- if(_size >= 2){
|
|
|
- ListNode<T> *tmp = getNode(_size - 2);
|
|
|
- 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;
|
|
|
- }
|
|
|
+ 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();
|
|
|
- }
|
|
|
+ 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;
|
|
|
+ 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);
|
|
|
+ ListNode<T> *tmp = getNode(index);
|
|
|
|
|
|
- return (tmp ? tmp->data : T());
|
|
|
+ return (tmp ? tmp->data : T());
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
void LinkedList<T>::clear(){
|
|
|
- while(size() > 0)
|
|
|
- shift();
|
|
|
+ while(size() > 0)
|
|
|
+ shift();
|
|
|
}
|
|
|
#endif
|