implement linked list
This commit is contained in:
@ -6,15 +6,17 @@
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class Wrapper {
|
class Wrapper {
|
||||||
|
private:
|
||||||
|
T value = NULL;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Wrapper(T value) : value(value) {}
|
Wrapper(T value) : value(value) {}
|
||||||
|
|
||||||
T value;
|
Wrapper<T>* next = NULL;
|
||||||
Wrapper<T>* next;
|
Wrapper<T>* prev = NULL;
|
||||||
Wrapper<T>* prev;
|
|
||||||
|
|
||||||
// Allow implicit conversion to make the ListIterator dereferencing work
|
// Allow conversion to make the ListIterator dereferencing work
|
||||||
operator T() {
|
explicit operator T() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -23,6 +25,8 @@ public:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
class LinkedListIterator : public ListIterator<T> {
|
class LinkedListIterator : public ListIterator<T> {
|
||||||
public:
|
public:
|
||||||
|
using Type = typename ListIterator<T>::Type;
|
||||||
|
|
||||||
LinkedListIterator& operator++() override {
|
LinkedListIterator& operator++() override {
|
||||||
// ptr is of type Wrapper<T>*
|
// ptr is of type Wrapper<T>*
|
||||||
this->ptr = this->ptr->next;
|
this->ptr = this->ptr->next;
|
||||||
@ -31,44 +35,237 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class LinkedList : public List<Wrapper<T>, LinkedListIterator<Wrapper<T>>> {
|
class LinkedList : public List<T, LinkedListIterator<Wrapper<T>>> {
|
||||||
public:
|
public:
|
||||||
using Type = typename List<Wrapper<T>, LinkedListIterator<Wrapper<T>>>::Type; // T is different from the List type (Wrapper<T>)
|
// Type is T
|
||||||
// so take the type out of the base class
|
using Type = typename List<T, LinkedListIterator<Wrapper<T>>>::Type; // T is different from the List type (Wrapper<T>)
|
||||||
using Iterator = typename List<Wrapper<T>, LinkedListIterator<Wrapper<T>>>::Iterator;
|
using Iterator = typename List<T, LinkedListIterator<Wrapper<T>>>::Iterator;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type* head;
|
unsigned int num_elements = 0;
|
||||||
Type* tail;
|
typename Iterator::Type* head = NULL;
|
||||||
|
typename Iterator::Type* tail = NULL;
|
||||||
|
|
||||||
|
typename Iterator::Type* get_wrapper(unsigned int i) {
|
||||||
|
typename Iterator::Type* current = this->head;
|
||||||
|
unsigned int pos = 0;
|
||||||
|
while (current != NULL) {
|
||||||
|
if (pos == i) {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
current = current->next;
|
||||||
|
pos = pos + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Type* begin_ptr() override {
|
typename Iterator::Type* begin_ptr() override {
|
||||||
return this->head;
|
return this->head;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* end_ptr() override {
|
typename Iterator::Type* end_ptr() override {
|
||||||
return this->tail->next;
|
return this->tail->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LinkedList() : head(NULL), tail(NULL) {}
|
unsigned int insert_at(Type e, unsigned int i) override {
|
||||||
|
if (i > this->size()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int insert(Type e) override {}
|
if (i == 0) {
|
||||||
unsigned int insert_at(Type e, unsigned int i) override {}
|
return this->insert_first(e);
|
||||||
|
}
|
||||||
|
|
||||||
Type remove_at(unsigned int i) override {}
|
if (i == this->size()) {
|
||||||
Type remove_first() override {}
|
return this->insert_last(e);
|
||||||
Type remove_last() override {}
|
}
|
||||||
bool remove(Type e) override {}
|
|
||||||
|
|
||||||
Type get(unsigned int i) const override {}
|
typename Iterator::Type* old_e = this->get_wrapper(i);
|
||||||
Type first() const override {}
|
typename Iterator::Type* new_e = new typename Iterator::Type(e);
|
||||||
Type last() const override {}
|
|
||||||
|
|
||||||
bool empty() const override {}
|
new_e->prev = old_e->prev;
|
||||||
unsigned int size() const override {}
|
new_e->next = old_e;
|
||||||
|
new_e->prev->next = new_e;
|
||||||
|
new_e->next->prev = new_e;
|
||||||
|
|
||||||
void print(OutStream& out) const override {}
|
this->num_elements = this->num_elements + 1;
|
||||||
|
return this->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int insert_first(Type e) override {
|
||||||
|
typename Iterator::Type* old_head = this->head;
|
||||||
|
this->head = new typename Iterator::Type(e);
|
||||||
|
|
||||||
|
this->head->prev = NULL;
|
||||||
|
this->head->next = old_head;
|
||||||
|
if (old_head != NULL) {
|
||||||
|
old_head->prev = this->head;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->tail == NULL) {
|
||||||
|
this->tail = this->head;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->num_elements = this->num_elements + 1;
|
||||||
|
return this->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int insert_last(Type e) override {
|
||||||
|
typename Iterator::Type* old_tail = this->tail;
|
||||||
|
this->tail = new typename Iterator::Type(e);
|
||||||
|
|
||||||
|
this->tail->next = NULL;
|
||||||
|
this->tail->prev = old_tail;
|
||||||
|
if (old_tail != NULL) {
|
||||||
|
old_tail->next = this->tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->head == NULL) {
|
||||||
|
this->head = this->tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->num_elements = this->num_elements + 1;
|
||||||
|
return this->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
Type remove_at(unsigned int i) override {
|
||||||
|
if (this->empty() || i >= this->size()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
return this->remove_first();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == this->size() - 1) {
|
||||||
|
return this->remove_last();
|
||||||
|
}
|
||||||
|
|
||||||
|
typename Iterator::Type* e = this->get_wrapper(i);
|
||||||
|
Type ret = (Type)*e;
|
||||||
|
|
||||||
|
e->next->prev = e->prev;
|
||||||
|
e->prev->next = e->next;
|
||||||
|
|
||||||
|
delete e;
|
||||||
|
this->num_elements = this->num_elements - 1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type remove_first() override {
|
||||||
|
if (this->empty()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type e = (Type)(*this->head);
|
||||||
|
typename Iterator::Type* old_head = this->head;
|
||||||
|
|
||||||
|
this->head = this->head->next;
|
||||||
|
if (this->head != NULL) {
|
||||||
|
this->head->prev = NULL;
|
||||||
|
} else {
|
||||||
|
this->tail = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete old_head;
|
||||||
|
this->num_elements = this->num_elements - 1;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type remove_last() override {
|
||||||
|
if (this->empty()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type e = (Type)(*this->tail);
|
||||||
|
typename Iterator::Type* old_tail = this->tail;
|
||||||
|
|
||||||
|
this->tail = this->tail->prev;
|
||||||
|
if (this->tail != NULL) {
|
||||||
|
this->tail->next = NULL;
|
||||||
|
} else {
|
||||||
|
this->head == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete old_tail;
|
||||||
|
this->num_elements = this->num_elements - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool remove(Type e) override {
|
||||||
|
unsigned int pos = 0;
|
||||||
|
typename Iterator::Type* wrapper = this->head;
|
||||||
|
while (wrapper != NULL) {
|
||||||
|
if ((Type)*wrapper == e) {
|
||||||
|
return remove_at(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapper = wrapper->next;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Type get(unsigned int i) const override {
|
||||||
|
if (i >= this->size()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
return (Type)*head;
|
||||||
|
}
|
||||||
|
if (i == this->size() - 1) {
|
||||||
|
return (Type)*tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
typename Iterator::Type* wrapper = this->head;
|
||||||
|
for (unsigned int pos = 0; pos < i; ++pos) {
|
||||||
|
wrapper = wrapper->next;
|
||||||
|
}
|
||||||
|
return (Type)*wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type first() const override {
|
||||||
|
if (this->empty()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Type)(*this->head);
|
||||||
|
}
|
||||||
|
|
||||||
|
Type last() const override {
|
||||||
|
if (this->empty()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Type)(*this->tail);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const override {
|
||||||
|
return this->size() == 0;
|
||||||
|
}
|
||||||
|
unsigned int size() const override {
|
||||||
|
return this->num_elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print(OutStream& out) const override {
|
||||||
|
if (this->empty()) {
|
||||||
|
out << "Print List (0 elements)" << endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out << "Print List (" << dec << this->size() << " elements): ";
|
||||||
|
typename Iterator::Type* current = this->head;
|
||||||
|
while (current != NULL) {
|
||||||
|
out << dec << (Type)(*current) << " ";
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
out << endl;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user