I have a Doubly linked List class wherein i have a function which uses my classes iterators to loop over the collection. However in 1 specific place it runs for an extra loop and I cannot figure out why.
current merge template
template <typename T>
void DlList<T>::merge(SortedList& other) {
iterator it = back_->prev_;
iterator oit = other.begin();
while (oit.current_->next_ != NULL) {
std::cout << *it << " " << *oit << std::endl;
it.current_->next_ = oit.current_;
back_->prev_ = oit.current_;
//back_->prev_->next_ = back_;
//other.back_->prev_ = other.back_->prev_->prev_;
it++;
oit++;
}
}
It always iterates and extra time and added a null node to the list and I don't understand why.
Any insight is greatly appricicated!
Edit Added full project examples to explain intention of function I am working on a templated data structure class which is a doubly linked list which uses sentinel nodes. The list is sorted based on insert() and I am working on a merge function wherein the nodes of each list must be combined into this->list. The nodes must be moved and not have new ones created. and if the same value exists in both lists the other node value must come after the current node value.
I coded what I thought was a logical implementation however the output I get is not as expected and the results do not make sense to me, so if anyone could explain how i am getting the results I have it would be greatly appreciated.
Class Definition
class SortedList {
struct Node {
T data_;
Node* next_;
Node* prev_;
Node(const T& data = T{}, Node* nx = nullptr, Node* pr = nullptr) {
data_ = data;
next_ = nx;
prev_ = pr;
}
};
Node* front_;
Node* back_;
public:
class const_iterator {
friend class SortedList;
Node* current_;
const_iterator(Node* n)
{
current_ = n;
}
public:
const_iterator() {
//Set to safe state
current_ = nullptr;
}
const_iterator& operator++() {
current_ = current_->next_;
return *this;
}
const_iterator operator++(int) {
const_iterator old = *this;
current_ = current_->next_;
return old;
}
const_iterator& operator--() {
current_ = current_->prev_;
return *this;
}
const_iterator operator--(int) {
const_iterator old = *this;
current_ = current_->prev_;
return old;
}
bool operator==(const_iterator rhs) {
return (current_ == rhs.current_) ? true : false;
}
bool operator!=(const_iterator rhs) {
return !(*this == rhs);
}
bool operator>(const_iterator rhs) {
return current_->data_ > rhs->current_->data_;
}
const T& operator*()const {
return current_->data_;
}
};
class iterator :public const_iterator {
friend SortedList;
iterator(Node* n) :const_iterator(n) {};
public:
iterator() : const_iterator() {};
//prefix
iterator& operator++() {
this->current_ = this->current_->next_;
return *this;
}
//post-fix
iterator operator++(int) {
iterator old = *this;
this->current_ = this->current_->next_;
return old;
}
iterator& operator--() {
this->current_ = this->current_->prev_;
return *this;
}
iterator operator--(int) {
iterator old = *this;
this->current_ = this->current_->prev_;
return old;
}
T& operator*() {
return this->current_->data_;
}
const T& operator*()const {
return this->current_->data;
}
};
SortedList(); //done
~SortedList();
SortedList(const SortedList& rhs);
SortedList& operator=(const SortedList& rhs);
SortedList(SortedList&& rhs);
SortedList& operator=(SortedList&& rhs);
iterator begin() {
return iterator(front_->next_);
}
iterator end() {
return iterator(back_);
}
const_iterator cbegin() const {
return const_iterator(front_->next_);
}
const_iterator cend() const {
return const_iterator(back_);
}
iterator insert(const T& data);
iterator search(const T& data);
const_iterator search(const T& data) const;
iterator erase(iterator it);
void merge(SortedList& other);
bool empty() const;
int size() const;
};
first merge function attempt
template <typename T>
void SortedList<T>::merge(SortedList& other) {
iterator it = this->begin();
iterator oit = other.begin();
while (oit != other.end()) {
std::cout << *oit << " " << *it << std::endl;
if (*oit < *it) {
oit.current_->prev_->next_ = oit.current_->next_;
oit.current_->next_->prev_ = oit.current_->prev_;
oit.current_->next_ = it.current_;
oit.current_->prev_ = it.current_->prev_;
it.current_->next_ = oit.current_;
}
else {
oit.current_->prev_->next_ = oit.current_->next_;
oit.current_->next_->prev_ = oit.current_->prev_;
oit.current_->next_ = it.current_->next_;
oit.current_->prev_ = it.current_;
it.current_->prev_ = oit.current_;
}
oit++;
it++;
}
}
main tester
int main() {
int num[] = { 3,5,1,2,6,8,9,11 };
int num2[] = { 1,5,4,6,12,7,8,9 };
SortedList<int> l;
SortedList<int> l2;
for (int i = 0; i < 8; i++)
{
l.insert(num[i]);
l2.insert(num2[i]);
}
SortedList<int>::iterator result;
SortedList<int>::iterator result2 = l2.begin();
result = l.begin();
while (result != l.end()) {
std::cout << *result << " " << *result2 << std::endl;
++result;
++result2;
}
l.merge(l2);
output
1 1
2 4
3 5
5 6
6 7
8 8
9 9
11 12
1 1
2 2
3 3
5 5
6 6
8 8
9 9
11 11
0 0
I dont understand why my second output is showing same the same values for *it and *oit I am pretty certain the error is in how I assign the the oit.current_->next & prev but i am unsure.
any insight is appriciated.
next_andback_. Instead just doback_->prev_->next_ = other.begin()->next_andback_->prev = other.end()->prev_.->prevpointers to make it doubly linked, but you may find some of it useful. To join the sorted sublists, you simply take list1tail->nextand set it equal to list2headand list2head->previs set to list1tail.