Created
March 18, 2014 12:33
-
-
Save ffoxin/9619173 to your computer and use it in GitHub Desktop.
Double linked list implementation. Just for fun.
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
#include <iostream> | |
namespace mystl | |
{ | |
#ifndef NULL | |
# define NULL ((void *)0) | |
#endif | |
template<typename T> | |
class List | |
{ | |
private: | |
class Node | |
{ | |
public: | |
Node(const T& val) : | |
obj(val), | |
prev(NULL), | |
next(NULL) | |
{ | |
} | |
T obj; | |
Node* prev; | |
Node* next; | |
}; | |
public: | |
class Iterator | |
{ | |
public: | |
friend class List; | |
Iterator() : | |
m_ptr(NULL) | |
{ | |
} | |
Iterator(const Iterator& it) : | |
m_ptr(it.m_ptr) | |
{ | |
} | |
~Iterator() | |
{ | |
} | |
Iterator& operator++() | |
{ | |
if (m_ptr) | |
{ | |
m_ptr = m_ptr->next; | |
} | |
return *this; | |
} | |
Iterator operator++(int) | |
{ | |
Iterator backup(*this); | |
operator++(); | |
return backup; | |
} | |
Iterator& operator--() | |
{ | |
if (m_ptr) | |
{ | |
m_ptr = m_ptr->prev; | |
return *this; | |
} | |
} | |
Iterator operator--(int) | |
{ | |
Iterator backup(*this); | |
operator--(); | |
return backup; | |
} | |
bool operator==(const Iterator& it) | |
{ | |
return m_ptr == it.m_ptr; | |
} | |
bool operator!=(const Iterator& it) | |
{ | |
return m_ptr != it.m_ptr; | |
} | |
T& operator*() | |
{ | |
return m_ptr->obj; | |
} | |
private: | |
Iterator(Node* ptr) : | |
m_ptr(ptr) | |
{ | |
} | |
private: | |
Node* m_ptr; | |
}; | |
List() : | |
m_top(NULL), | |
m_back(NULL), | |
m_size(0) | |
{ | |
} | |
List(size_t n, const T& val = T()) | |
{ | |
m_top = m_back = new Node(val); | |
for (size_t i = 1; i < n; ++i) | |
{ | |
Node* node = new Node(val); | |
m_back->next = node; | |
node->prev = m_back; | |
m_back = node; | |
} | |
m_size = n; | |
} | |
List(Iterator first, Iterator last) | |
{ | |
m_top = m_back = new Node(*first); | |
m_size = 1; | |
for (++first, ++last; first != last; ++first) | |
{ | |
Node* node = new Node(*first); | |
m_back->next = node; | |
node->prev = m_back; | |
m_back = node; | |
m_size++; | |
} | |
} | |
List(const List& list) : | |
m_size(list.size()) | |
{ | |
Node* current = list.m_top->next; | |
m_top = m_back = new Node(current->obj); | |
for (size_t i = 1; i < list.size(); ++i) | |
{ | |
current = current->next; | |
Node* node = new Node(current->obj); | |
m_back->next = node; | |
node->prev = m_back; | |
m_back = node; | |
} | |
} | |
~List() | |
{ | |
while (m_top != m_back) | |
{ | |
m_top = m_top->next; | |
delete m_top->prev; | |
} | |
delete m_top; | |
} | |
void push_back(const T& val) | |
{ | |
Node* node = new Node(val); | |
if (m_back) | |
{ | |
m_back->next = node; | |
node->prev = m_back; | |
m_back = node; | |
} | |
else | |
{ | |
m_top = m_back = new Node(val); | |
} | |
m_size++; | |
} | |
void push_front(const T& val) | |
{ | |
Node* node = new Node(val); | |
if (m_top) | |
{ | |
m_top->prev = node; | |
node->next = m_top; | |
m_top = node; | |
} | |
else | |
{ | |
m_top = m_back = new Node(val); | |
} | |
m_size++; | |
} | |
void pop_back() | |
{ | |
if (m_back) | |
{ | |
if (m_back != m_top) | |
{ | |
m_back = m_back->prev; | |
delete m_back->next; | |
m_back->next = NULL; | |
} | |
else | |
{ | |
delete m_back; | |
m_top = m_back = NULL; | |
} | |
} | |
m_size--; | |
} | |
void pop_top() | |
{ | |
if (m_top) | |
{ | |
if (m_top != m_back) | |
{ | |
m_top = m_top->next; | |
delete m_top->prev; | |
m_top->prev = NULL; | |
} | |
else | |
{ | |
delete m_top; | |
m_top = m_back = NULL; | |
} | |
} | |
m_size--; | |
} | |
T& top() | |
{ | |
return m_top->obj; | |
} | |
T& back() | |
{ | |
return m_back->obj; | |
} | |
Iterator begin() | |
{ | |
return Iterator(m_top); | |
} | |
Iterator end() | |
{ | |
return Iterator(NULL); | |
} | |
size_t size() const | |
{ | |
return m_size; | |
} | |
private: | |
Node *m_top, *m_back; | |
size_t m_size; | |
}; | |
} | |
int main() | |
{ | |
mystl::List<int> l1; | |
mystl::List<int> l2(5); | |
mystl::List<int> l3(8, 4); | |
mystl::List<int> l4; | |
for (int i = 1; i < 11; ++i) | |
{ | |
l4.push_back(i); | |
} | |
mystl::List<int> l5; | |
for (int i = 1; i < 11; ++i) | |
{ | |
l5.push_front(i); | |
} | |
std::cout << "l1 : " << l1.size() << std::endl; | |
for (mystl::List<int>::Iterator it = l1.begin(); it != l1.end(); ++it) | |
{ | |
std::cout << *it << std::endl; | |
} | |
std::cout << "l2 : " << l2.size() << std::endl; | |
for (mystl::List<int>::Iterator it = l2.begin(); it != l2.end(); ++it) | |
{ | |
std::cout << *it << std::endl; | |
} | |
std::cout << "l3 : " << l3.size() << std::endl; | |
for (mystl::List<int>::Iterator it = l3.begin(); it != l3.end(); ++it) | |
{ | |
std::cout << *it << std::endl; | |
} | |
std::cout << "l4 : " << l4.size() << std::endl; | |
while (l4.size()) | |
{ | |
std::cout << l4.top() << std::endl; | |
l4.pop_top(); | |
} | |
std::cout << "l5 : " << l5.size() << std::endl; | |
while (l5.size()) | |
{ | |
std::cout << l5.back() << std::endl; | |
l5.pop_back(); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment