Last active
August 6, 2017 13:00
-
-
Save rmi111/0e3edd87f68f3deb4138a0c5fa503d8d to your computer and use it in GitHub Desktop.
Linked List With Iterators
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// LinkedListIterative.h | |
// DataStructure | |
// | |
// Created by Md Aminuzzaman on 5/17/17. | |
// Copyright © 2017 Md Aminuzzaman. All rights reserved. | |
// | |
#ifndef LinkedListIterative_h | |
#define LinkedListIterative_h | |
#include <cstdio> | |
#pragma once | |
using std::swap; | |
template <typename T> | |
class LinkedList; | |
template < class NodeT > | |
class Iterators; | |
template <typename T> | |
class Node; | |
template < class T, class Pointer, class Reference > | |
class Iterator | |
{ | |
private: | |
Node<T> *node; | |
public: | |
Iterator() : node(nullptr) {} | |
Iterator(Node<T> *node) : node(node) {} | |
Iterator(Node<const T> *node) : node(node) {} | |
Iterator(const Iterator& iterator) : node(iterator.node) {} | |
Iterator& operator= (const Iterator& rhs) | |
{ | |
if( this != &rhs ) | |
{ | |
node = rhs.node; | |
} | |
} | |
Iterator& operator++() | |
{ | |
node = node->next; | |
return *this; | |
} | |
Iterator& operator+(size_t index) | |
{ | |
while( index-- > 0 && ( node != nullptr ) ) | |
{ | |
++this; | |
} | |
return *this; | |
} | |
Iterator& operator[](size_t index) | |
{ | |
while( index-- > 0 && ( node != nullptr ) ) | |
{ | |
++this; | |
} | |
return *this; | |
} | |
bool operator==(const Iterator &iter) | |
{ | |
return node == iter.node; | |
} | |
bool operator!=(const Iterator &iter) | |
{ | |
return node != iter.node; | |
} | |
Reference& operator*() { return node->data; } | |
}; | |
/*template <class NodeT> | |
class Iterators | |
{ | |
private: | |
friend class LinkedList<typename NodeT::value_type>; | |
NodeT *node; | |
public: | |
Iterators() : node(nullptr) {} | |
//Iterators(NodeT *node) : node(node) {} | |
Iterators(NodeT *node) : node(node) {} | |
Iterators(const Iterators& iterator) : node(iterator.node) {} | |
Iterators& operator= (const Iterators& rhs) | |
{ | |
if( this != &rhs ) | |
{ | |
node = rhs.node; | |
} | |
} | |
Iterators& operator++() | |
{ | |
node = node->next; | |
return *this; | |
} | |
Iterators& operator+(size_t index) | |
{ | |
while( index-- > 0 && ( node != nullptr ) ) | |
{ | |
++this; | |
} | |
return *this; | |
} | |
/*Iterators& operator[](size_t index) | |
{ | |
while( index-- > 0 && ( node != nullptr ) ) | |
{ | |
++this; | |
} | |
return *this; | |
}*/ | |
/*bool operator==(const Iterators &iter) | |
{ | |
return node == iter.node; | |
} | |
bool operator!=(const Iterators &iter) | |
{ | |
return node != iter.node; | |
} | |
//typename NodeT::value_type& operator*() const { return node->data; } | |
}; | |
*/ | |
template<typename T> | |
class Node | |
{ | |
private: | |
friend class LinkedList<T>; | |
friend class Iterators<Node<T>>; | |
friend class Iterators<const Node<T>>; | |
T data; | |
Node<T> *next; | |
Node() : next(nullptr) {} | |
Node(const T& data) : data(data),next(nullptr) {} | |
public: | |
typedef T value_type; | |
}; | |
template <typename T> | |
class LinkedList | |
{ | |
private: | |
size_t size; | |
Node<T> *first; | |
Node<T> *last; | |
Node<T>* createNode(const T &item) | |
{ | |
Node<T> *node = new Node<T>; | |
node->data = item; | |
node->next = nullptr; | |
return node; | |
} | |
//LinkedList(const LinkedList& list){} | |
LinkedList& operator=(const LinkedList& list){} | |
public: | |
typedef Iterator<T,T*, T&> iterator; | |
typedef Iterator<T,const T*, const T&> const_iterator; | |
//typedef Iterator<Node<T>> iterator; | |
//typedef Iterator<const Node<T>> const_iterator; | |
LinkedList() : size(0), first(nullptr), last(nullptr) | |
{ | |
} | |
LinkedList(const LinkedList& list) : size(0), first(nullptr), last(nullptr) | |
{ | |
for( const_iterator iter = list.begin() ; iter != list.end(); ++ iter ) | |
{ | |
add(*iter); | |
} | |
} | |
// Add item at the end of the list | |
void add(const T& item) | |
{ | |
Node<T> *node = createNode(item); | |
if(first == nullptr) | |
{ | |
first = node; | |
last = node; | |
} | |
else | |
{ | |
last->next = node; | |
last = node; | |
} | |
++size; | |
} | |
void add(const T& item,size_t index) | |
{ | |
if( size == 0 ) | |
{ | |
add(item); | |
} | |
else if( index == 0 && size > 0 ) | |
{ | |
addToFirst(item); | |
} | |
else if( index >= size ) | |
{ | |
addToLast(item); | |
} | |
else | |
{ | |
Node<T> *prev = first; | |
Node<T> *curr = first; | |
int i = 0; | |
while( i++ < index ) | |
{ | |
prev = curr; | |
curr = curr->next; | |
} | |
Node<T> *node = createNode(item); | |
prev->next = node; | |
node->next = curr; | |
++size; | |
} | |
} | |
void addToFirst(const T& item) | |
{ | |
Node<T> *node = createNode(item); | |
node->next = first; | |
first = node; | |
if(size == 0) | |
last = node; | |
++size; | |
} | |
void addToLast(const T& item) | |
{ | |
Node<T> *node = createNode(item); | |
last->next = node; | |
last = node; | |
if(size == 0) | |
first = node; | |
++size; | |
} | |
void removeFirst() | |
{ | |
if( first == nullptr ) | |
return; | |
Node<T> *temp = first; | |
first = first->next; | |
--size; | |
delete temp; | |
if( size == 0 ) | |
last = first; | |
} | |
void remove(const size_t index) | |
{ | |
if( size == 0 || index > size - 1 ) | |
throw std::out_of_range("Out of range"); | |
if(index == 0) | |
{ | |
removeFirst(); | |
return; | |
} | |
Node<T> *curr = first; | |
Node<T> *prev = first; | |
size_t i(0); | |
while( i++ < index ) | |
{ | |
prev = curr; | |
curr = curr->next; | |
} | |
if( curr == last ) | |
{ | |
last = prev; | |
} | |
prev->next = curr->next; | |
delete curr; | |
--size; | |
} | |
void removeLast() | |
{ | |
if( first == nullptr ) | |
return; | |
Node<T> *curr = first; | |
Node<T> *prev = first; | |
while( curr != last ) | |
{ | |
prev = curr; | |
curr = curr->next; | |
} | |
prev->next = nullptr; | |
delete last; | |
last = prev; | |
--size; | |
if( size == 0 ) | |
first = last; | |
} | |
T& getItem(size_t index) const | |
{ | |
if(index > size) | |
throw std::out_of_range("index out of bound!"); | |
Node<T> *curr = first; | |
size_t i = 0; | |
while ( i++ != index ) | |
curr = curr->next; | |
return curr->data; | |
} | |
size_t length() const | |
{ | |
return size; | |
} | |
iterator begin() | |
{ | |
return iterator(first); | |
} | |
iterator end() | |
{ | |
return iterator(last); | |
} | |
const_iterator begin() const | |
{ | |
return const_iterator(); | |
} | |
const_iterator end() const | |
{ | |
return const_iterator(); | |
} | |
~LinkedList() | |
{ | |
Node<T> *curr = first; | |
while( curr != last ) | |
{ | |
Node<T> *temp = curr; | |
curr = curr->next; | |
delete temp; | |
} | |
} | |
}; | |
#endif | |
/* LinkedListIterative_h */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment