This is my complete code.
#pragma once
#include <utility>
#include<iostream>
template<typename T>
class DList {
private:
/*This is the Node object used for each list element
data members
@data - represents the data held inside the Node and of type T or the List's data type
@prev - previous element in the list
@next - next element in the list
*/
struct Node {
T data_;
Node* next_;
Node* prev_;
/*constructor
takes the following values as parameters
@ T data - type of data and value of data to be stored for this Node's data,
safe empty state by default
@Node* next - next Node in list
sets to NULL pointer by default
@Node* prev - pre Node in list
sets to NULL pointer by default
*/
Node(const T& data = T{}, Node* next = nullptr, Node* prev = nullptr) {
data_ = data;
next_ = next;
prev_ = prev;
}
};
/* head_ is the first node in the list and tail_ is the last node */
Node* head_;
Node* tail_;
/*Number of elements in the list*/
int size_;
public:
/*Iterator that is const in nature, i.e. cannot modifty the iterator after creation*/
class const_iterator {
protected:
Node* curr;
private:
friend class DList;
/*Constructor that sets Node to Node passed*/
const_iterator(Node* pass) {
curr = pass;
}
public:
/* A Constructor that sets internal Node to nullptr*/
const_iterator() {
curr = nullptr;
}
/*This function checks that the passed iterator is equal to the current
one including pointing to the same Node in the list*/
bool operator==(const_iterator rhs) {
return curr == rhs.curr;
}
/*This function is the opposite of the one above in that it
checks if the iterator passed is not equal in both being the
same object and pointing to the same Node in the list*/
bool operator!=(const_iterator rhs) {
return curr != rhs.curr;
}
/*This makes the interal Node point to the next Node in
the list before returning the current object as a point*/
const_iterator operator++() {
curr = curr->next_;
return *this;
}
/*This does the same as above but returns the previos
Node in the list as a iterator rather then *this*/
const_iterator operator++(int) {
const_iterator next = *this;
curr = curr->next_;
return next;
}
/*This moves the internal Node to the previous
object before returning the current object's
pointer*/
const_iterator operator--() {
curr = curr->prev_;
return *this;
}
/*Same as above but return a new iterator
that points to the previous Node rather
than *this*/
const_iterator operator--(int) {
const_iterator prev = *this;
curr = curr->prev_;
return prev;
}
/*Return the data held by this Node*/
const T& operator*() const {
return curr->data_;
}
};
/*This is the same as above except not const in nature i.e. can modifiy*/
class iterator :public const_iterator {
friend class DList;
/*Constructor that takes a parameter sets the Node to the Node passed*/
iterator(Node* pass) {
this->curr = pass;
}
/*Returns Node for Quicksort*/
Node* getNode() {
return this->curr;
}
public:
/*Constructor for this class
One that takes no parameters sets interal node used by interator to nullptr
*/
iterator() {
this->curr = nullptr;
}
/*Return the data held by this Node*/
T& operator*() {
return this->curr->data_;
}
/*This makes the interal Node point to the next Node in
the list before returning the current object as a point*/
iterator operator++() {
this->curr = this->curr->next_;
return *this;
}
/*This does the same as above but returns the previos
Node in the list as a iterator rather then *this*/
iterator operator++(int) {
iterator next = *this;
this->curr = this->curr->next_;
return next;
}
/*This moves the internal Node to the previous
object before returning the current object's
Same as above but return a new iterator */
iterator operator--() {
this->curr = this->curr->prev_;
return *this;
}
/*This moves the internal Node to the previous
object before returning the current object's
Same as above but return a new iterator
that points to the previous Node rather
than *this*/
iterator operator--(int) {
iterator prev = *this;
this->curr = this->curr->prev_;
return prev;
}
};
private:
//Swap function for nodes
void swap ( Node* a, Node* b ) {
Node *t = a;
a = b;
b = t;
}
//Partion function for nodes
Node* partition(Node *l, Node *h)
{
T x = h->data_;
Node *i = l->prev_;
Node* j = new Node();
for (j; j != h; j = j->next_) {
if (j->data_ <= x) {
i = (i == nullptr)? l : i->next_;
swap(i, j);
}
}
i = (i == nullptr)? l : i->next_;
swap(i, h);
return i;
}
/*this does qsort recursively on the elements from the Node at the first iterator passed up to
and including the Node at iterator two*/
void qSortrecursive(iterator first, iterator second) {
Node* h = first.getNode();
Node* l = second.getNode();
if (h != NULL && l != h && l != h->next_)
{
struct Node *p = partition(l, h);
qSortrecursive(l, p->prev_);
qSortrecursive(p->next_, h);
}
}
/*This does qsort as above but Iterative and not recursively*/
void qSortIterative(iterator first, iterator second) {
Node* h = first.getNode();
Node* l = second.getNode();
if (h != NULL && l != h && l != h->next_) {
struct Node *p = partition(l, h);
qSortIterative(l, p->prev_);
qSortIterative(p->next_, h);
}
}
public:
/*Constructor sets list to empty state
i.e. head_ and tail_ are nullptr and
size is 0, no Nodes*/
DList() {
head_ = new Node();
tail_ = new Node();
head_->next_ = tail_;
tail_->prev_ = head_;
size_ = 0;
}
/*Creates and returns a iterator to the beginning of the list*/
iterator begin() {
iterator begin(head_->next_);
return begin;
}
/*Returns a iterator to one after the end of the list after
creating a iterator that does so*/
iterator end() {
iterator end(tail_);
return end;
}
/*This is the same as iterator begin but creates a const_iterator
rather then a iterator*/
const_iterator begin() const {
const_iterator begin(head_->next_);
return begin;
}
/*This creates a const iterator to the Node after the end of the list*/
const_iterator end() const {
const_iterator end(tail_);
return end;
}
/* Pushs a new Node into the list's first element with a value
passed to it as the Node's data member*/
void push_front(const T& data) {
Node* first = head_->next_; //it is ok if this
//is back sentinel
Node* temp = new Node(data, first, head_);
head_->next_ = temp;
first->prev_ = temp;
size_++;
}
/* Pushs a new Node into the list's last element with a value
passed to it as the Node's data member*/
void push_back(const T& data) {
Node* last = tail_->prev_;
Node* temp = new Node(data, tail_, last);
tail_->prev_ = temp;
last->next_ = temp;
size_++;
}
/* Removes the Node at the beginning of the list*/
void pop_front() {
Node* first = head_->next_;
if (first != tail_) {
Node* secondFirst = first->next_;
head_->next_ = secondFirst;
secondFirst->prev_ = head_;
delete first;
size_--;
}
}
/*Removes the Node at the end of the list*/
void pop_back() {
Node* last = tail_->prev_;
if (last != head_) {
Node* secondLast = last->prev_;
tail_->prev_ = secondLast;
secondLast->next_ = tail_;
delete last;
size_--;
}
}
/*Insert Node at the point of the iterator passed with
the data passed becoming the inseted Node's data member*/
iterator insert(iterator loc, const T& data) {
Node* curr = loc.curr;
std::cout << loc.curr;
Node* prev = curr->prev_;
Node* New = new Node(data, curr, prev);
prev->next_ = New;
curr->prev_ = New;
size_++;
loc--;
return loc;
}
/*Removes the element at the position passsed in the iterator argument*/
void erase(iterator it) {
Node* loc = it.curr;
Node* next = loc->next_;
Node* prev = loc->prev_;
prev->next_ = next;
next->prev_ = prev;
size_--;
delete loc;
}
/*Removes all elements from the first to the last*/
void erase(iterator first, iterator last) {
iterator it = first;
while(++it != last) {
erase(it);
it = first;
}
erase(first);
}
/*Searchs for a Node with the data passed as a arugment if found
return a iterator founding to it otherwise return iterator pointing
to one element beyond end of list*/
iterator search(T& data) {
iterator it = begin();
while (it != end()) {
if (it.curr->data_ == data) {
return it;
}
it++;
}
return end();
}
/*Searchs for a Node with the data passed as a arguument if found
return a const iterator founding to it otherwise return iterator pointing
to one element beyond end of list*/
const_iterator search(const T& data) const {
const_iterator it = begin();
while (it != end()) {
if (it.data_->data_ == data) {
return it;
}
it++;
}
return end();
}
/*Quicksort wrapper for iterative verision*/
void sortIterative() {
iterator last = end()--;
qSortIterative(begin(),last);
}
void qSort(){
iterator last = end()--;
qSortrecursive(begin(),last);
}
/*Returns true if list has size set to zero or no Nodes otherwise false*/
bool empty() const {
if (size_ == 0) {
return true;
}
else {
return false;
}
}
/*Returns size of list*/
int size() const {
return size_;
}
/*Destructor, destorys and cleans up each Node's member when the
list is destoryed*/
~DList() {
if (empty()) {
return;
}
iterator itBegin = begin();
iterator itEnd = end();
erase(itBegin,itEnd);
}
/*Copy Constructor, creates a new List that is a copy of the src list
passed as a argument*/
DList(const DList& src) {
head_ = new Node();
tail_ = new Node();
head_->next_ = tail_;
tail_->prev_ = head_;
size_ = src.size_;
if (src.empty() == false) {
iterator i = end();
const_iterator c = src.end();
c--;
while(c != src.begin()){
i = insert(i,*c);
c--;
}
push_front(*c);
}
}
/*Copy Assigment operator, assigns a new List that is a copy of the src list
passed as a argument*/
DList& operator=(const DList& src) {
head_ = new Node();
tail_ = new Node();
head_->next_ = tail_;
tail_->prev_ = head_;
size_ = src.size_;
if (src.empty() == false && src.head_ != head_) {
iterator i = end();
const_iterator c = src.end();
c--;
while(c != src.begin()){
i = insert(i,*c);
c--;
}
push_front(*c);
}
return *this;
}
/*Move constructor - sets list to list passed in agrument src but steals or
moves it other rather then copies the values of the Nodes and themselves*/
DList(DList&& src) {
if (src.head_ == tail_) {
head_ = tail_ = nullptr;
size_ = 0;
}
else {
head_ = std::move(src.head_);
tail_ = std::move(src.tail_);
size_ = std::move(src.size_);
src.head_ = nullptr;
src.tail_ = nullptr;
size_ = src.size_;
}
}
/*Move Assignment operator - sets list to list passed in agrument src but steals or
moves it other rather then copies the values of the Nodes and themselves*/
DList& operator=(DList&& src) {
head_ = std::move(src.head_);
tail_ = std::move(src.tail_);
size_ = std::move(src.size_);
src.head_ = nullptr;
src.tail_ = nullptr;
size_ = src.size_;
return *this;
}
};
The reason I am asking is there appears to be no good examples for quicksort *with Node* swap not data swap which is what I want. So can someone point me to an example that does it by swapping the nodes and not the data.