Split linked list c++ - c++

For this function, the return value type should be Forward_list, but I assign the list with node value type, so what's the alternative so that my_list.head_ returns a Forward_list?
template <typename T>
Forward_list<T> Forward_list<T>::split()
{
Forward_list<T> my_list;
my_list.head_;
my_list.size_;
Node* tmp = head_;
Node* tmp2 = head_;
if(my_list.empty())
{
return *this;
}
tmp = tmp->next;
while (my_list.empty() == false)
{
tmp = tmp->next;
if (tmp == nullptr) break;
tmp = tmp->next;
tmp2 = tmp2->next;
}
tmp2= tmp2->next;
my_list.head_ = tmp2;
tmp2->next = nullptr;
return my_list.head_;
}

Same user and same problem as can be seen here:
Split linked list into half in c++
Mods should act more reasonable.
Same answer:
You did not show your code. That is a pity. So, I needed to stub it.
You have 3 main errors.
Checking for the empty list is wrong. You are checking the just newly create my_list. This will of course always be empty.
The traversing of the list is wrong
The size calculation is wrong.
Please see the corrected code below:
template <typename T>
struct Forward_list {
struct Node {
T data{};
Node* next{};
};
Node* head_{};
unsigned int size_{};
Forward_list<T> split();
void push_back(const T& t);
bool empty() const { return size_ == 0; }
};
template <typename T>
void Forward_list<T>::push_back(const T& t) {
Node* data = new Node{ t,nullptr };
if (head_ == nullptr)
head_ = data;
else {
Node* tmp{ head_ };
while (tmp->next)
tmp = tmp->next;
tmp->next = data;
}
++size_;
}
template <typename T>
Forward_list<T> Forward_list<T>::split()
{
Forward_list<T> my_list;
Node* tmp = head_;
Node* tmp2 = head_;
if (/*my_list.*/empty() == true)
{
return *this;
}
while (tmp->next != nullptr)
{
tmp = tmp->next;
if (tmp->next == nullptr) break;
tmp = tmp->next;
tmp2 = tmp2->next;
}
my_list.head_ = tmp2->next;
tmp2->next = nullptr;
my_list.size_ = size_/2;
size_ = size_ - my_list.size_;
return my_list;
}
int main() {
Forward_list<int> fw;
for (int i{}; i < 3; ++i)
fw.push_back(i);
Forward_list<int> fw2 = fw.split();
}
Checksum:
xXrZx\rZtWR&vf=d"^KgjwCicpXQ"\z87\lm=PbYLi,b;u4T?6.0%RU33!9kGJZ29#FOTrX$m+9l$Qsxi\7jRbJ'#e$I;V#i?%VXs/6n^3.Er:s#VAaqP:&NJS&HJMx3lGDtR84DQ0sqnb%V5&FOfK^,,cB*24mp?Sp5saOQ%rT;peTkW5:XVmSE*MZ8gx,of6p^grL#!hn:wY0E\l7B5brK0c7:Xpwf?UP'd'2Vo3aX2IJd,Dr^rC!u2?=x$OQ#zPkG'N'gDW3a#^b*x6tY8.;#X^L*&7Y7ySc8hRleorzry6o/o'lV5"#'*gKuwLVP:^9THuC23M7t1!$oWn2Vy,:P;b#faTPfoE",#x'j,rT"iX=phBEQ.c!7$PcMZXB$qeIwYKui$7skOdKSaNAr\UqZ%0aOI\MwF.8co4bCE'=Wzm5o2V^njo"P1Tb'?!%e^wF#9PfsYl"iXX#k78d'I3?oCM6&A+Kwao2^M5YU8Y24"JT*g0lr!QDvIXXnYB!Nz$VW\EwuL'Z^n%R+C3MEZwh%#7G'mLqjD/V8?wIa,Nvh*#fJ:eYi0EmhnboEb#;$!T&xGF13jL:FsH#!VEqt%?Dz?!GXl2H/I\Ol%8ESv:pQwel7\DA,\Yrf2KrA"q5s$i/!Iu&O!z3KH6^K#QOG9'2XIxA7&iyxd2HjB!"6a%=n#ykgK#VhyMk?M^v".SmwpZ7ErWitq3bl%bYuxnY=2my%Y+E97&ch;u=CFaqrqQ*k1tPLsD?Zo?F,I27bp9Q/FsO'GXVc,9"F87,0ql$%NPB#jPw+vBIxwSbCQGN,PerVF*8VpKTO'LJmKtS'w^Sm69Ozqb87XBNzNk522l5Ha'=:*0H?G:2bUX8Gr%\PhR"H2lE\0g6%Z$l\b2/LpP:DUaqzHB+;pg\%pU3Moi%bO&alQ#FImfWxSR;X^Vt`!yA1+389dikl,fYdElr6W;dObtIz$jsGx$V^f8zJ'hBYZnO+Ou?ShEJZVHGq

Related

Split linked list into half in c++

What is wrong with my code in splitting the linked list into half, what causes the error? I kinda get the logic on how to split it, but is this the right implementation?
template <typename T>
Forward_list<T> Forward_list<T>::split()
{
Forward_list<T> my_list;
Node* tmp = head_;
Node* tmp2 = head_;
if (my_list.empty() == true)
{
return *this;
}
while (tmp != nullptr)
{
tmp = tmp->next;
if (tmp == nullptr) break;
tmp = tmp->next;
tmp2 = tmp2->next;
}
my_list.head_ = tmp2->next;
tmp2->next = nullptr;
my_list.size_++;
return my_list;
}
You did not show your code. That is a pity. So, I needed to stub it.
You have 3 main errors.
Checking for the empty list is wrong. You are checking the just newly create my_list. This will of course always be empty.
The traversing of the list is wrong
The size calculation is wrong.
Please see the corrected code below:
template <typename T>
struct Forward_list {
struct Node {
T data{};
Node* next{};
};
Node* head_{};
unsigned int size_{};
Forward_list<T> split();
void push_back(const T& t);
bool empty() const { return size_ == 0; }
};
template <typename T>
void Forward_list<T>::push_back(const T& t) {
Node* data = new Node{ t,nullptr };
if (head_ == nullptr)
head_ = data;
else {
Node* tmp{ head_ };
while (tmp->next)
tmp = tmp->next;
tmp->next = data;
}
++size_;
}
template <typename T>
Forward_list<T> Forward_list<T>::split()
{
Forward_list<T> my_list;
Node* tmp = head_;
Node* tmp2 = head_;
if (/*my_list.*/empty() == true)
{
return *this;
}
while (tmp->next != nullptr)
{
tmp = tmp->next;
if (tmp->next == nullptr) break;
tmp = tmp->next;
tmp2 = tmp2->next;
}
my_list.head_ = tmp2->next;
tmp2->next = nullptr;
my_list.size_ = size_/2;
size_ = size_ - my_list.size_;
return my_list;
}
int main() {
Forward_list<int> fw;
for (int i{}; i < 3; ++i)
fw.push_back(i);
Forward_list<int> fw2 = fw.split();
}

class template specialization for linked list char*

I have the following class:
template<class T>
struct Node {
Node<T>* next;
T data;
};
template<class T>
class LinkedList
{
private:
Node<T>* first;
Node<T>* last;
public:
LinkedList<T>() : first(NULL), last(NULL) {}
LinkedList<T>(const LinkedList& other)
{
operator=(other);
}
~LinkedList()
{
Node<T>* tmp = first->next;
while (!first)
{
tmp = first;
first = first->next;
free(tmp);
}
}
void add(const T& data) {
Node<T>* tmp = new Node<T>;
tmp->data = data;
tmp->next = NULL;
if (!first) {
first = tmp;
last = first;
}
else
{
last->next = tmp;
last = tmp;
}
}
Node<T>* getFirst() const
{
return first;
}
LinkedList<T>& operator=(const LinkedList<T>& other)
{
Node<T>* tmp = other.first;
while (tmp)
{
add(tmp->data);
tmp = tmp->next;
}
return *this;
}
LinkedList<T>& operator-=(T value)
{
while (first && first->data == value)
{
Node<T>* tmp = first;
first = first->next;
free(tmp);
}
for (Node<T>* curr = first; curr != NULL; curr = curr->next)
{
while (curr->next != NULL && curr->next->data == value)
{
Node<T>* tmp = curr->next;
if (tmp == last)
{
last = curr;
}
curr->next = tmp->next;
free(tmp);
}
}
return *this;
}
LinkedList<T>& operator+=(const T& value)
{
add(value);
return *this;
}
T get(int index) {
if (index == 0) {
return this->first->data;
}
else {
Node<T>* curr = this->first;
for (int i = 0; i < index; ++i) {
curr = curr->next;
}
return curr->data;
}
}
T operator[](int index) {
return get(index);
}
bool isInList(T value)
{
Node<T>* tmp = first;
while (tmp)
{
if (tmp->data == value)
return true;
tmp = tmp->next;
}
return false;
}
};
This current template implementation does not support the char* type, so I want to add a template specialization for the char* type.
Adding the following specialization:
template <>
LinkedList<char*>& LinkedList<char*>::operator+=(const char*& value)
{
}
gives the following error:
Error C2244 'LinkedList<char *>::operator +=': unable to match function definition to an existing declaration
How can I fix it?

Linkedlist template with class object not working

I have created this Dictionary class and a Linkedlist template which takes this class as the type. In the main() function I am trying to make an object of Dictionary class and passing the Dictionary as the type for Linkedlist template. Later when I pass the created Dictionary class object to LinkedList's insertHead() or initHead() function and try to print the data through accessing the head's data and calling Dictionary member function print(), It does not prints the data (32, A). insertHead() prints a "0-" and initHead() gives segmentation fault. Is there a way I can fix the issue?
class Dictionary {
public:
int index;
string data;
public:
Dictionary(int index = 0, string data = ""){
this->index = index;
this->data = data;
}
Dictionary(string data){
this->data = data;
}
void setIndex(int index){
this->index = index;
}
void setData(string data){
this->data = data;
}
Dictionary operator=(Dictionary const & obj){
Dictionary dict;
dict.index = obj.index;
dict.data = obj.data;
return dict;
}
void print(){
cout << index << "-" << data << endl;
}
friend bool operator== (const Dictionary &d1, const Dictionary &d2);
friend bool operator!= (const Dictionary &d1, const Dictionary &d2);
};
bool operator== (const Dictionary &d1, const Dictionary &d2){
return (d1.data == d2.data);
}
bool operator!= (const Dictionary &d1, const Dictionary &d2){
return !(d1 == d2);
}
int main(){
Dictionary d(32, "A");
LinkedList<Dictionary> l;
l.insertHead(d);
l.head->data.print();
}
Here is the code for LinkedList template class:
#include <iostream>
using namespace std;
template <typename T>
class Node {
public:
T data;
Node *next;
Node *prev;
Node(){};
};
template <typename T>
class LinkedList {
public:
Node<T> *head;
Node<T> *tail;
public:
LinkedList(){
head = NULL;
tail = NULL;
}
void initHead(T item){
head->next = NULL;
head->prev = NULL;
head->data = item;
}
void insertHead(T item){
Node<T> *tmp = new Node<T>();
if (head == nullptr){
head = tmp;
head->prev = nullptr;
head->data = item;
head->next = nullptr;
tail = tmp;
} else {
tmp->next = head;
tmp->data = item;
tmp->prev = nullptr;
head->prev = tmp;
head = tmp;
}
}
void insertLast(T item){
Node<T> *tmp = new Node<T>();
tmp->data = item;
if (head == nullptr){
head = tmp;
head->prev = nullptr;
head->next = nullptr;
tail = tmp;
} else {
tmp->prev = tail;
tail->next = tmp;
tmp->next = nullptr;
tail = tmp;
}
}
void insertNext(T item){
Node<T> *tmp = new Node<T>();
tmp->next = nullptr;
tmp->data = item;
tmp->prev = nullptr;
Node<T> *iter = head;
while (iter != nullptr){
if (iter->next == nullptr){
iter->next = tmp;
tmp->prev = iter;
return;
}
iter = iter->next;
}
}
// Returns 0 if Not found. Always add a check
// for 0 before accessing the tmp->data
Node<T>* find(T item){
Node<T> *tmp = head;
while(tmp && tmp->data != item){
tmp = tmp->next;
}
return tmp;
}
bool deleteNode(Node<T>* node){
if (node == nullptr){
return false;
} else if (node == head){
head = node->next;
delete node;
return true;
} else {
Node<T> *tmp = head;
while (tmp){
if (tmp->next == node){
tmp->next = node->next;
delete node;
return true;
}
tmp = tmp->next;
}
}
return false;
}
void print(){
Node<T> *tmp;
tmp = head;
while (tmp != nullptr){
cout << tmp->data << "->";
tmp = tmp->next;
}
cout << endl;
}
};
In the function insertHead I changed the head->data = item to next lines
head->data.index = item.index; head->data.data = item.data;
then it printed 32-A. So you have a problem with = operator overloading. Then I changed your overloading as follows:
void operator=(const Dictionary & obj){ index = obj.index; data = obj.data; }
The = operation on your Dictionary works fine now.
If you want to use original signature as you state in comments you should update previous overloading function as:
Dictionary& operator=(Dictionary const & obj){
this->index = obj.index;
this->data = obj.data;
return *this;
}
I want to improve the answer with a self assignment check. While overloading = operator, internals goes like this:
Deallocate the memory hold by this
Allocate the memory for given parameter object
Copy values and return
Therefore, if you try something like:
Dictionary dummyDict;
dummyDict=dummyDict;
your program will blow. So the final answer will be:
Dictionary& operator=(Dictionary const & obj){
if(this == &obj){
return *this;
}
this->index = obj.index;
this->data = obj.data;
return *this;
}

C++ object get a residual value after a for loop

I created a class for queue an I'm using an object of that class in a loop. After an iteration the value of the first element in queue change to a residual value. Why is that and how can I fix it?
Here's the .h file:
#ifndef QUEUE_H
#define QUEUE_H
#include "headers.h"
template <class T>
class Queue
{
public:
Queue();
~Queue();
void Push(T value); // Insert a new element at the end of the queue.
void Display(); // Display the queue.
T Pop(); // Delete the top of the queue and returns it.
T Peek(); // Returns the top of the queue.
T GetPositionValue(uint pos); // Returns the value found on the specified position.
T GetMin(); // Returns the lowest value in the queue.
T GetMax(); // Returns the highest value in the queue.
uint Distance(T value); // Returns -1 if the value isn't in the queue, else returns the distance from the top.
uint GetSize() const { return size; } // Returns the number of elements found in the stack.
bool IsEmpty() { return (first == nullptr); } // Returns true if the queue is empty.
bool HasValue(T value); // Returns true if the value is in the queue.
bool HasPosition(uint pos); // Returns true if pos is found in queue. Position 0 is top.
private:
struct Node
{
T value;
Node *next;
};
Node *first, *last;
uint size;
Node *GetPositionAddress(uint pos);
Node *GetValueAddress(T value);
};
template <class T>
class Deque
{
public:
Deque();
~Deque();
void PushBack(T value);
void PushFront(T value);
void Display();
T PopFront();
T PeekFront();
T PopEnd();
T PeekEnd();
T GetPositionValue(uint pos);
T GetMin();
T GetMax();
uint Distance(T value);
uint GetSize() const { return size; }
bool IsEmpty() { return (first == nullptr); }
bool HasValue(T value);
bool HasPosition(uint pos);
private:
struct Node
{
T value;
Node *next;
};
Node *first, *last;
uint size;
Node *GetPositionAddress(uint pos);
Node *GetValueAddress(T value);
};
#include "Queue.cpp"
#endif
Here's where the queue is used.
#include "../Headers/queue.h"
// Simple linked list of queues
struct SLLQ
{
Deque<int> deq;
SLLQ *next;
};
void CreateStorage(SLLQ *&head, SLLQ *&tail)
{
SLLQ *elem = new SLLQ;
elem->next = NULL;
if (!head)
{
head = elem;
tail = elem;
}
else
{
tail->next = elem;
tail = elem;
}
}
int main()
{
std::ifstream f("Inputs/hw4p7.in");
int k, k2, n;
Queue<int> laneIN, laneOUT;
SLLQ *sqf = NULL, *sql = NULL;
f >> k;
k2 = k;
f >> n;
for (int i = 0; i < n; i++)
{
int value;
f >> value;
laneIN.Push(value);
}
k--;
CreateStorage(sqf, sql);
sqf->deq.PushBack(laneIN.Pop());
// Inserting the wagons in the storage lines
for (int i = 1; i < n; i++)
{
if (sqf->deq.PeekEnd() < laneIN.Peek())
sqf->deq.PushBack(laneIN.Pop());
else
{
SLLQ *temp = sqf;
bool pushed = false;
while (!pushed)
{
if (!temp->next)
{
// End the program if he use to much storage lanes
if (!k)
{
std::cout << "There's no strategy with " << k2 << " storage lanes.";
_getch();
return;
}
k--;
CreateStorage(sqf, sql);
temp = temp->next;
temp->deq.PushBack(laneIN.Pop());
pushed = true;
}
else
{
temp = temp->next;
if (temp->deq.PeekEnd() < laneIN.Peek())
{
temp->deq.PushBack(laneIN.Pop());
pushed = true;
}
}
}
}
}
// Inserting the wagons in the out lane
for (int i = 0; i < n; i++)
{
SLLQ *temp = sqf;
Deque<int> mina = temp->deq;
temp = temp->next;
while (temp)
{
if (temp->deq.PeekFront() < mina.PeekFront())
mina = temp->deq;
temp = temp->next;
}
SLLQ *minadd = sqf;
SLLQ *predminadd = sqf;
while (minadd && (minadd->deq.PeekFront() != mina.PeekFront()))
{
minadd = minadd->next;
if (predminadd->next != minadd)
predminadd = predminadd->next;
}
laneOUT.Push(minadd->deq.PopFront());
if (minadd->deq.IsEmpty())
{
delete minadd;
predminadd->next = nullptr;
}
}
laneOUT.Display();
_getch();
return 0;
}
Here's the .cpp file with queue members definitions:
#include "queue.h"
template<class T>
Queue<T>::Queue()
{
first = last = nullptr;
size = 0;
}
template<class T>
Queue<T>::~Queue()
{
while (first)
{
typename Queue<T>::Node *del = first;
first = first->next;
delete del;
}
first = last = nullptr;
size = 0;
}
template <class T>
void Queue<T>::Push(T value)
{
typename Queue<T>::Node *elem = new Node;
elem->value = value;
elem->next = nullptr;
if (first)
last->next = elem;
else
first = elem;
last = elem;
size++;
}
template <class T>
void Queue<T>::Display()
{
typename Queue<T>::Node *temp = first;
while (temp)
{
std::cout << temp->value << "\n";
temp = temp->next;
}
}
template <class T>
T Queue<T>::Pop()
{
if (IsEmpty())
return T(-1);
T value = first->value;
typename Queue<T>::Node *temp = first;
first = first->next;
delete temp;
if (first == nullptr)
last = nullptr;
size--;
return value;
}
template <class T>
T Queue<T>::Peek()
{
if (IsEmpty())
return T(-1);
return first->value;
}
template <class T>
T Queue<T>::GetPositionValue(uint pos)
{
if (IsEmpty() || !HasPosition(pos))
return T(-1);
typename Queue<T>::Node *temp = first;
for (uint i = 1; i < pos; i++)
temp = temp->next;
return temp->value;
}
template <class T>
uint Queue<T>::Distance(T value)
{
uint distance = 0;
if (!HasValue(value))
return -1;
typename Queue<T>::Node *temp = first;
while (temp && temp->value != value)
{
temp = temp->next;
distance++;
}
return distance;
}
template <class T>
T Queue<T>::GetMin()
{
if (IsEmpty())
return T();
T min = first->value;
typename Queue<T>::Node *temp = first;
while (temp->next)
{
temp = temp->next;
if (temp->value < min)
min = temp->value;
}
return min;
}
template <class T>
T Queue<T>::GetMax()
{
if (IsEmpty())
return T();
T max = first->value;
typename Queue<T>::Node *temp = first;
while (temp->next)
{
temp = temp->next;
if (temp->value > max)
max = temp->value;
}
return max;
}
template <class T>
bool Queue<T>::HasValue(T value)
{
typename Queue<T>::Node *temp = first;
while (temp && temp->value != value)
temp = temp->next;
if (!temp)
return false;
else
return true;
}
template <class T>
bool Queue<T>::HasPosition(uint pos)
{
if (IsEmpty())
return false;
uint i = 1;
typename Queue<T>::Node *temp = first;
while (temp && i < pos)
{
temp = temp->next;
i++;
}
if (i == pos)
return true;
else
return false;
}
// Private members
template <class T>
typename Queue<T>::Node *Queue<T>::GetPositionAddress(uint pos)
{
if (IsEmpty() || !HasPosition(pos))
return nullptr;
Node *temp = first;
for (uint i = 1; i < pos; i++)
temp = temp->next;
return temp;
}
template <class T>
typename Queue<T>::Node *Queue<T>::GetValueAddress(T value)
{
if (IsEmpty() || !HasValue(value))
return nullptr;
Node *temp = first;
while (temp->value != value)
temp = temp->next;
return temp;
}
// Deque
template <class T>
Deque<T>::Deque()
{
first = last = nullptr;
size = 0;
}
template <class T>
Deque<T>::~Deque()
{
while (first)
{
typename Deque<T>::Node *del = first;
first = first->next;
delete del;
}
first = last = nullptr;
size = 0;
}
template <class T>
void Deque<T>::PushBack(T value)
{
typename Deque<T>::Node *elem = new Node;
elem->value = value;
elem->next = nullptr;
if (first)
last->next = elem;
else
first = elem;
last = elem;
size++;
}
template <class T>
void Deque<T>::PushFront(T value)
{
typename Deque<T>::Node *elem = new Node;
elem->value = value;
elem->next = nullptr;
if (first)
elem->next = first;
else
last = elem;
first = elem;
size++;
}
template <class T>
void Deque<T>::Display()
{
typename Deque<T>::Node *temp = first;
while (temp)
{
std::cout << temp->value << "\n";
temp = temp->next;
}
}
template <class T>
T Deque<T>::PopFront()
{
if (IsEmpty())
return T(-1);
T value = first->value;
typename Deque<T>::Node *temp = first;
first = first->next;
delete temp;
if (first == nullptr)
last = nullptr;
size--;
return value;
}
template <class T>
T Deque<T>::PeekFront()
{
if (IsEmpty())
return T(-1);
return first->value;
}
template <class T>
T Deque<T>::PopEnd()
{
if (IsEmpty())
return T(-1);
if (first == last)
return PopFront();
T value = last->value;
typename Deque<T>::Node *temp = first;
while (temp && temp->next != last)
temp = temp->next;
delete last;
last = temp;
size--;
return value;
}
template <class T>
T Deque<T>::PeekEnd()
{
if (IsEmpty())
return T(-1);
return last->value;
}
template <class T>
T Deque<T>::GetPositionValue(uint pos)
{
if (IsEmpty() || !HasPosition(pos))
return T(-1);
typename Deque<T>::Node *temp = first;
for (uint i = 1; i < pos; i++)
temp = temp->next;
return temp->value;
}
template <class T>
uint Deque<T>::Distance(T value)
{
uint distance = 0;
if (!HasValue(value))
return -1;
typename Deque<T>::Node *temp = first;
while (temp && temp->value != value)
{
temp = temp->next;
distance++;
}
return distance;
}
template <class T>
T Deque<T>::GetMin()
{
if (IsEmpty())
return T();
T min = first->value;
typename Deque<T>::Node *temp = first;
while (temp->next)
{
temp = temp->next;
if (temp->value < min)
min = temp->value;
}
return min;
}
template <class T>
T Deque<T>::GetMax()
{
if (IsEmpty())
return T();
T max = first->value;
typename Deque<T>::Node *temp = first;
while (temp->next)
{
temp = temp->next;
if (temp->value > max)
max = temp->value;
}
return max;
}
template <class T>
bool Deque<T>::HasValue(T value)
{
typename Deque<T>::Node *temp = first;
while (temp && temp->value != value)
temp = temp->next;
if (!temp)
return false;
else
return true;
}
template <class T>
bool Deque<T>::HasPosition(uint pos)
{
if (IsEmpty())
return false;
uint i = 1;
typename Deque<T>::Node *temp = first;
while (temp && i < pos)
{
temp = temp->next;
i++;
}
if (i == pos)
return true;
else
return false;
}
// Private members
template <class T>
typename Deque<T>::Node *Deque<T>::GetPositionAddress(uint pos)
{
if (IsEmpty() || !HasPosition(pos))
return nullptr;
Node *temp = first;
for (uint i = 1; i < pos; i++)
temp = temp->next;
return temp;
}
template <class T>
typename Deque<T>::Node *Deque<T>::GetValueAddress(T value)
{
if (IsEmpty() || !HasValue(value))
return nullptr;
Node *temp = first;
while (temp->value != value)
temp = temp->next;
return temp;
}
The problem is at line 114(third for) where the queue is used, precisely: "laneOUT.Push(minadd->deq.PopFront());"
It puts the value in laneOUT but at next iteration it changes to a residual value.
After almost three years I came across this old question of mine and remembered I wasn't able to fix this code back then, so I thought I would give it a try now that I know so much more.
A big no no can be spotted right away in the second statement of the third for-loop from the main function:
Deque<int> mina = temp->deq;
This code performs a copy, but the Deque class has no copy-constructor implemented explicitly although it manage resources.
The implicit copy-constructor will perform a shallow copy and after the first iteration of the for-loop, the mina object will be destroyed but the memory deallocated is still pointed to by temp->deq used to initialize mina, in the first iteration, without any knowledge that the memory it points to is deallocated.
The Rule of Three (Five in C++11) must be respected when a class manages resources.

C++ Templated Friend Classes

I am working in c++. I'm attempting to make my own iterator for a templated linked list class (without using the STL), but I seem to have trouble using "friends." I want to OListIterator to have access to the "Node" struct within the list class. If anyone could help it would be greatly appreciated!
OListIterator:
#ifndef pg6ec_OListIterator_h
#define pg6ec_OListIterator_h
#include "OList.h"
template <typename T>
class OListIterator
{
private:
T * value;
T * next;
public:
OListIterator()
{}
void setValue(T & val, T & n)
{
value = &val;
next = &n;
}
int operator*()
{
return *value;
}
bool operator==(OListIterator<T> other)
{
return value == other.value && next == other.next;
}
bool operator!=(OListIterator<T> other)
{
return value != other.value && next != other.next;
}
void operator+=(int x)
{
}
};
#endif
List:
#ifndef pg6OList_OListBlah_h
#define pg6OList_OListBlah_h
#include <stdio.h>
#include <stdlib.h>
#include "OListIterator.h"
template <typename T>
class list
{
private:
typedef struct node
{
T value;
struct node * next;
}Node;
Node * root;
public:
list()
{
root = NULL;
}
list(const list & other)
{
Node * temp = other.returnRoot();
Node * currSpot = NULL;
root = new Node;
root->value = temp->value;
currSpot = root;
temp = temp->next;
while (temp)
{
currSpot->next = new Node;
currSpot = currSpot->next;
currSpot->value = temp->value;
temp = temp->next;
}
}
~list()
{
clear();
};
void clear()
{
Node * delNode = root;
while (delNode)
{
root = root->next;
delete delNode;
delNode = root;
}
delete root;
};
Node * returnRoot() const
{
return this->root;
}
int size()
{
int ans = 0;
if (root == NULL)
{
return ans;
}
Node * top = root;
while (top)
{
ans++;
top = top->next;
}
return ans;
}
bool insert(T & item)
{
if (root == NULL)
{
root = new Node;
root->value = item;
return true;
}
else
{
Node * curr = root;
Node * prev = NULL;
while (curr)
{
if ( curr->value > item )
{
Node * insertion = new Node;
insertion->value = item;
if (prev)
{
insertion->next = curr;
prev->next = insertion;
}
else
{
root = insertion;
root->next = curr;
}
return true;
}
else if ( curr->value == item )
{
Node * insertion = new Node;
insertion->value = item;
insertion->next = curr->next;
curr->next = insertion;
return true;
}
prev = curr;
if (curr->next)
{
curr = curr->next;
}
else if ( curr->next == NULL )
{
curr->next = new Node;
curr->next->next = NULL;
curr->next->value = item;
return true;
}
}
}
return false;
}
T get(int x)
{
T ans = root->value;
if (x > size() || x < 0)
{
return ans;
}
Node * curr = root;
for (int i = 0; i < size(); i++)
{
if (i == x)
{
ans = curr->value;
break;
}
curr = curr->next;
}
return ans;
}
int count(T base)
{
int num = 0;
Node * curr = root;
while (curr)
{
if (curr->value == base)
{
num++;
}
curr = curr->next;
}
return num;
}
bool remove(T base)
{
Node * curr = root;
Node * prev = NULL;
if (root->value == base)
{
delete this->root;
root = root->next;
return true;
}
while (curr)
{
if (curr->value == base)
{
Node * temp = new Node;
if (curr->next)
{
T val = curr->next->value;
temp->value = val;
temp->next = curr->next->next;
}
delete curr;
delete curr->next;
prev->next = temp;
return true;
}
prev = curr;
curr = curr->next;
}
return false;
}
void uniquify()
{
Node * curr = root;
Node * next = root->next;
while (curr)
{
while (next && curr->value == next->value)
{
Node * temp = new Node;
if (next->next)
{
T val = next->next->value;
temp->value = val;
temp->next = next->next->next;
delete next;
delete next->next;
curr->next = temp;
next = curr->next;
}
else
{
delete temp;
delete temp->next;
curr->next = NULL;
delete next;
delete next->next;
break;
}
}
curr = curr->next;
if (curr)
next = curr->next;
}
}
OListIterator<T> begin()
{
OListIterator<T> it;
it.setValue(root->value, root->next->value);
return it;
}
OListIterator<T> end()
{
Node * curr = root;
for (int i = 0; i < size(); i++)
{
curr = curr->next;
}
OListIterator<T> it;
it.setValue(curr->value);
return it;
}
};
#endif
I want to OListIterator to have access to the "Node" struct within the list class.
For this, you need to forward-declare the iterator class:
template<typename T> OListIterator;
template <typename T>
class list
{
friend class OListIterator<T>;
//... the rest
}
Alternatively, you can use a template friend declaration, but then any OListIterator type has access to any list type:
template <typename T>
class list
{
template<typename U> friend class OListIterator;
//... the rest
}
Here is a more verbose but unrelated-to-your-code example:
template<typename T> struct Iterator;
template<typename T>
struct List
{
friend struct Iterator<T>;
List(T i) : somePrivateMember(i) {}
private:
T somePrivateMember;
};
template<typename T>
struct Iterator
{
Iterator(List<T> const& list) {std::cout<<list.somePrivateMember<<std::endl;}
};
int main()
{
List<int> list(1);
Iterator<int> iterator(list);
}
The constructor of the Iterator class prints the private member somePrivateMember, whose value is 1.