Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 104 additions & 47 deletions LinkedList.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,54 @@
#include <stddef.h>

template<class T>
struct ListNode
{
struct ListNode {
T data;
ListNode<T> *next;
};

template <typename T>
class LinkedList{
//Ranged-based for loop support.
template<class T>
class INode
{
private:
ListNode<T>* current;
public:
INode(ListNode<T>*);
bool operator!=(INode);
T& operator*();
void operator++();
~INode();
};

template<class T>
INode<T>::INode(ListNode<T>* start)
: current(start)
{
}

template<class T>
bool INode<T>::operator!=(INode) {
return (current != nullptr);
}

template<class T>
T& INode<T>::operator*() {
return current->data;
}

template<class T>
void INode<T>::operator++() {
current = current->next;
}

template<class T>
INode<T>::~INode() {

}

template <typename T>
class LinkedList
{
protected:
int _size;
ListNode<T> *root;
Expand All @@ -33,6 +72,7 @@ class LinkedList{
// Helps "get" method, by saving last position
ListNode<T> *lastNodeGot;
int lastIndexGot;

// isCached should be set to FALSE
// everytime the list suffer changes
bool isCached;
Expand All @@ -50,47 +90,65 @@ class LinkedList{
Returns current size of LinkedList
*/
virtual int size();

/*
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;
*/
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);

/*
Ranged-based for loop support.
*/
INode<T> begin();

/*
Ranged-based for loop support.
*/
INode<T> end();

/*
Clear the entire array
*/
Expand All @@ -101,7 +159,9 @@ class LinkedList{
*/
virtual void sort(int (*cmp)(T &, T &));

// add support to array brakets [] operator
/*
add support to array brakets [] operator
*/
inline T& operator[](int index);
inline T& operator[](size_t& i) { return this->get(i); }
inline const T& operator[](const size_t& i) const { return this->get(i); }
Expand All @@ -111,20 +171,13 @@ class LinkedList{
// Initialize LinkedList with false values
template<typename T>
LinkedList<T>::LinkedList()
: root(NULL), last(NULL), _size(0), lastNodeGot(root), lastIndexGot(0), isCached(false)
{
root=NULL;
last=NULL;
_size=0;

lastNodeGot = root;
lastIndexGot = 0;
isCached = false;
}

// Clear Nodes and free Memory
template<typename T>
LinkedList<T>::~LinkedList()
{
LinkedList<T>::~LinkedList() {
ListNode<T>* tmp;
while(root!=NULL)
{
Expand All @@ -142,26 +195,26 @@ LinkedList<T>::~LinkedList()
*/

template<typename T>
ListNode<T>* LinkedList<T>::getNode(int index){
ListNode<T>* LinkedList<T>::getNode(int index) {

int _pos = 0;
ListNode<T>* current = root;

// Check if the node trying to get is
// immediatly AFTER the previous got one
if(isCached && lastIndexGot <= index){
if(isCached && lastIndexGot <= index) {
_pos = lastIndexGot;
current = lastNodeGot;
}

while(_pos < index && current){
while(_pos < index && current) {
current = current->next;

_pos++;
}

// Check if the object index got is the same as the required
if(_pos == index){
if(_pos == index) {
isCached = true;
lastIndexGot = index;
lastNodeGot = current;
Expand All @@ -173,19 +226,19 @@ ListNode<T>* LinkedList<T>::getNode(int index){
}

template<typename T>
int LinkedList<T>::size(){
int LinkedList<T>::size() {
return _size;
}

template<typename T>
LinkedList<T>::LinkedList(int sizeIndex, T _t){
LinkedList<T>::LinkedList(int sizeIndex, T _t) {
for (int i = 0; i < sizeIndex; i++){
add(_t);
}
}

template<typename T>
bool LinkedList<T>::add(int index, T _t){
bool LinkedList<T>::add(int index, T _t) {

if(index >= _size)
return add(_t);
Expand All @@ -206,7 +259,7 @@ bool LinkedList<T>::add(int index, T _t){
}

template<typename T>
bool LinkedList<T>::add(T _t){
bool LinkedList<T>::add(T _t) {

ListNode<T> *tmp = new ListNode<T>();
tmp->data = _t;
Expand All @@ -229,7 +282,7 @@ bool LinkedList<T>::add(T _t){
}

template<typename T>
bool LinkedList<T>::unshift(T _t){
bool LinkedList<T>::unshift(T _t) {

if(_size == 0)
return add(_t);
Expand All @@ -245,14 +298,13 @@ bool LinkedList<T>::unshift(T _t){
return true;
}


template<typename T>
T& LinkedList<T>::operator[](int index) {
return getNode(index)->data;
}

template<typename T>
bool LinkedList<T>::set(int index, T _t){
bool LinkedList<T>::set(int index, T _t) {
// Check if index position is in bounds
if(index < 0 || index >= _size)
return false;
Expand All @@ -262,21 +314,21 @@ bool LinkedList<T>::set(int index, T _t){
}

template<typename T>
T LinkedList<T>::pop(){
T LinkedList<T>::pop() {
if(_size <= 0)
return T();

isCached = false;

if(_size >= 2){
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{
} else {
// Only one element left on the list
T ret = root->data;
delete(root);
Expand All @@ -288,11 +340,11 @@ T LinkedList<T>::pop(){
}

template<typename T>
T LinkedList<T>::shift(){
T LinkedList<T>::shift() {
if(_size <= 0)
return T();

if(_size > 1){
if(_size > 1) {
ListNode<T> *_next = root->next;
T ret = root->data;
delete(root);
Expand All @@ -301,25 +353,23 @@ T LinkedList<T>::shift(){
isCached = false;

return ret;
}else{
} else {
// Only one left, then pop()
return pop();
}

}

template<typename T>
T LinkedList<T>::remove(int index){
if (index < 0 || index >= _size)
{
T LinkedList<T>::remove(int index) {
if (index < 0 || index >= _size) {
return T();
}

if(index == 0)
return shift();

if (index == _size-1)
{
if (index == _size-1) {
return pop();
}

Expand All @@ -333,22 +383,32 @@ T LinkedList<T>::remove(int index){
return ret;
}


template<typename T>
T LinkedList<T>::get(int index){
T LinkedList<T>::get(int index) {
ListNode<T> *tmp = getNode(index);

return (tmp ? tmp->data : T());
}

template<typename T>
void LinkedList<T>::clear(){
INode<T> LinkedList<T>::begin() {
if (!size()) return nullptr;
return INode<T>(root);
}

template<typename T>
INode<T> LinkedList<T>::end() {
return INode<T>(last);
}

template<typename T>
void LinkedList<T>::clear() {
while(size() > 0)
shift();
}

template<typename T>
void LinkedList<T>::sort(int (*cmp)(T &, T &)){
void LinkedList<T>::sort(int (*cmp)(T &, T &)) {
if(_size < 2) return; // trivial case;

for(;;) {
Expand All @@ -364,8 +424,7 @@ void LinkedList<T>::sort(int (*cmp)(T &, T &)){
last = a_end;
isCached = false;
return;
}
else {
} else {
break;
}
}
Expand All @@ -383,8 +442,7 @@ void LinkedList<T>::sort(int (*cmp)(T &, T &)){
*joinPoint = a;
joinPoint = &a->next;
a = a->next;
}
else {
} else {
*joinPoint = b;
joinPoint = &b->next;
b = b->next;
Expand All @@ -396,8 +454,7 @@ void LinkedList<T>::sort(int (*cmp)(T &, T &)){
while(a->next) a = a->next;
a->next = tail;
joinPoint = &a->next;
}
else {
} else {
*joinPoint = b;
while(b->next) b = b->next;
b->next = tail;
Expand All @@ -416,4 +473,4 @@ ListNode<T>* LinkedList<T>::findEndOfSortedString(ListNode<T> *p, int (*cmp)(T &
return p;
}

#endif
#endif
Loading