Created
September 22, 2014 23:44
-
-
Save dgodfrey206/f42956141f4fc6027825 to your computer and use it in GitHub Desktop.
A simple deque implementation
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> | |
#include <stdexcept> | |
template <typename Item> | |
class Deque | |
{ | |
class iterator; | |
class node; | |
public: | |
Deque() = default; | |
bool isEmpty(); | |
int size(); | |
void addFirst(Item item); | |
Item removeFirst(); | |
Item removeLast(); | |
iterator begin(); | |
iterator end(); | |
private: | |
node* head{nullptr}; | |
node* tail{nullptr}; | |
int count{0}; | |
void increase_count() { ++count; } | |
void decrease_count() | |
{ | |
--count; | |
if (isEmpty()) | |
tail = head; | |
} | |
}; | |
template <typename Item> | |
bool Deque<Item>::isEmpty() | |
{ | |
return !head || count == 0; | |
} | |
template <typename Item> | |
void Deque<Item>::addFirst(Item item) | |
{ | |
node* newHead = new node(item); | |
if (isEmpty()) | |
{ | |
head = newHead; | |
tail = head; | |
} | |
else | |
{ | |
newHead->next = head; | |
head = newHead; | |
if (tail == nullptr) tail = newHead; | |
} | |
increase_count(); | |
tail->next = nullptr; | |
} | |
template <typename Item> | |
Item Deque<Item>::removeFirst() | |
{ | |
if (isEmpty()) | |
{ | |
throw std::out_of_range("Deque is empty."); | |
} | |
Item oldValue = head->data; | |
node* oldNode = head; | |
head->next = head->next->next; | |
delete oldNode; | |
decrease_count(); | |
return oldValue; | |
} | |
template <typename Item> | |
Item Deque<Item>::removeLast() | |
{ | |
if (isEmpty()) | |
{ | |
throw std::out_of_range("Deque is empty."); | |
} | |
Item oldValue = tail->data; | |
node* oneBefore = head; | |
if (oneBefore->next == nullptr) | |
{ | |
delete oneBefore; | |
head = nullptr; | |
tail = nullptr; | |
} | |
else | |
{ | |
while (oneBefore->next != nullptr) | |
oneBefore = oneBefore->next; | |
delete oneBefore->next; | |
tail = oneBefore; | |
} | |
decrease_count(); | |
return oldValue; | |
} | |
template <typename Item> | |
typename Deque<Item>::iterator Deque<Item>::begin() | |
{ | |
return iterator(head); | |
} | |
template <typename Item> | |
typename Deque<Item>::iterator Deque<Item>::end() | |
{ | |
return iterator(); | |
} | |
template <typename Item> | |
class Deque<Item>::iterator | |
{ | |
public: | |
iterator() : iter(nullptr) { } | |
iterator(node* first) : iter(first) { } | |
Item& operator*() { return iter->data; } | |
Item const& operator*() const { return iter->data; } | |
iterator& operator++() { update(); return *this; } | |
iterator operator++(int) { iterator copy(*this); ++*this; return copy; } | |
friend bool operator==(typename Deque<Item>::iterator const& lhs, typename Deque<Item>::iterator const& rhs) | |
{ return lhs.iter == rhs.iter; } | |
friend bool operator!=(typename Deque<Item>::iterator const& lhs, typename Deque<Item>::iterator const& rhs) | |
{ return !(lhs == rhs); } | |
private: | |
node* iter; | |
void update() { iter = iter->next; } | |
}; | |
template <typename Item> | |
class Deque<Item>::node | |
{ | |
Item data; | |
node* next; | |
friend class Deque<Item>; | |
friend class Deque<Item>::iterator; | |
public: | |
node(Item item) : data(item) { } | |
}; | |
int main() | |
{ | |
Deque<int> deque; | |
deque.addFirst(3); | |
deque.addFirst(10); | |
deque.addFirst(35); | |
for (auto& x : deque) | |
{ | |
std::cout << x << " "; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment