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();
}
Related
I have a utility library that I developed and noticed I have a memory leak in the SinglyLinkedList class. After debugging the code, I could not find why I have a memory leak. This is the test case I am using in the main function:
#include <iostream>
#include "SinglyLinkedList.h"
using namespace std;
int main() {
cout << "Program operating..." << endl;
do {
SinglyLinkedList<int> list = SinglyLinkedList<int>();
list.add(1);
list.add(1);
list.add(1);
} while (true);
cout << "Program terminated..." << endl;
}
Here is SinglyLinkedList.h file. It contains the SinglyLinkedNode and SinglyLinkedList class.
#pragma once
// SinglyLinkedNode
template <class T>
class SinglyLinkedNode {
public:
T data;
SinglyLinkedNode<T>* nextNode;
SinglyLinkedNode(T data);
SinglyLinkedNode(const SinglyLinkedNode& singlyLinkedNode);
void operator = (const SinglyLinkedNode& singlyLinkedNode);
~SinglyLinkedNode();
};
template <class T>
SinglyLinkedNode<T>::SinglyLinkedNode(T data) {
this->data = data;
nextNode = nullptr;
}
template <class T>
SinglyLinkedNode<T>::SinglyLinkedNode(const SinglyLinkedNode& singlyLinkedNode) {
this->data = singlyLinkedNode.data;
nextNode = nullptr;
}
template <class T>
void SinglyLinkedNode<T>::operator = (const SinglyLinkedNode& singlyLinkedNode) {
this->data = singlyLinkedNode.data;
nextNode = nullptr;
}
template <class T>
SinglyLinkedNode<T>::~SinglyLinkedNode() {
nextNode = nullptr;
}
// SinglyLinkedList
template <class E>
class SinglyLinkedList {
private:
unsigned int size;
public:
SinglyLinkedNode<E>* head;
SinglyLinkedNode<E>* tail;
SinglyLinkedList();
SinglyLinkedList(const SinglyLinkedList& singlyLinkedList); // O(n)
void operator = (const SinglyLinkedList<E> singlyLinkedList); // O(n)
SinglyLinkedNode<E>* add(E data); // O(1)
SinglyLinkedNode<E>* addAt(unsigned int i, E data); // O(n)
SinglyLinkedNode<E>* addToHead(E data); // O(1)
SinglyLinkedNode<E>* addToTail(E data); // O(n)
SinglyLinkedNode<E>* getNodeAt(unsigned int i); // O(n)
SinglyLinkedNode<E>* getHeadNode(); // O(1)
SinglyLinkedNode<E>* getTailNode(); // O(1)
bool contains(SinglyLinkedNode<E>* singlyLinkedNode); // O(n)
E getDataAt(unsigned int i); // O(n)
E getHeadData(); // O(1)
E getTailData(); // O(1)
bool contains(E data); // O(n)
E remove(E data); // O(n)
E removeAt(unsigned int i); // O(n)
E removeHead(); // O(1)
E removeTail(); // O(size)
void clear(); // O(size)
bool isEmpty(); // O(1)
unsigned int getSize(); // O(1)
~SinglyLinkedList();
};
template <class E>
SinglyLinkedList<E>::SinglyLinkedList() {
head = nullptr;
tail = nullptr;
size = 0;
}
template <class E>
SinglyLinkedList<E>::SinglyLinkedList(const SinglyLinkedList<E>& singlyLinkedList) {
head = nullptr;
tail = nullptr;
size = 0;
SinglyLinkedNode<E>* currentNode = singlyLinkedList.head;
while (currentNode != nullptr) {
addToTail(currentNode->data);
currentNode = currentNode->nextNode;
}
}
template <class E>
void SinglyLinkedList<E>::operator = (const SinglyLinkedList<E> singlyLinkedList) {
head = nullptr;
tail = nullptr;
size = 0;
SinglyLinkedNode<E>* currentNode = singlyLinkedList.head;
while (currentNode != nullptr) {
addToTail(currentNode->data);
currentNode = currentNode->nextNode;
}
}
template <class E>
SinglyLinkedNode<E>* SinglyLinkedList<E>::add(E data) {
return addToTail(data);
}
template <class E>
SinglyLinkedNode<E>* SinglyLinkedList<E>::addAt(unsigned int i, E data) {
if (i > size)
return nullptr;
SinglyLinkedNode<E>* singlyLinkedNode = new SinglyLinkedNode<E>(data);
if (size == 0) {
head = singlyLinkedNode;
tail = singlyLinkedNode;
size++;
return singlyLinkedNode;
}
if (i == 0) {
singlyLinkedNode->nextNode = head;
head = singlyLinkedNode;
size++;
return singlyLinkedNode;
}
SinglyLinkedNode<E>* currentNode = head;
for (unsigned int j = 1; j < i; j++)
currentNode = currentNode->nextNode;
singlyLinkedNode->nextNode = currentNode->nextNode;
currentNode->nextNode = singlyLinkedNode;
size++;
return singlyLinkedNode;
}
template <class E>
SinglyLinkedNode<E>* SinglyLinkedList<E>::addToHead(E data) {
SinglyLinkedNode<E>* singlyLinkedNode = new SinglyLinkedNode<E>(data);
if (size == 0) {
head = singlyLinkedNode;
tail = singlyLinkedNode;
size++;
return singlyLinkedNode;
}
singlyLinkedNode->nextNode = head;
head = singlyLinkedNode;
size++;
return singlyLinkedNode;
}
template <class E>
SinglyLinkedNode<E>* SinglyLinkedList<E>::addToTail(E data) {
SinglyLinkedNode<E>* singlyLinkedNode = new SinglyLinkedNode<E>(data);
if (size == 0) {
head = singlyLinkedNode;
tail = singlyLinkedNode;
size++;
return singlyLinkedNode;
}
tail->nextNode = new SinglyLinkedNode<E>(data);
tail = tail->nextNode;
size++;
return singlyLinkedNode;
}
template <class E>
SinglyLinkedNode<E>* SinglyLinkedList<E>::getNodeAt(unsigned int i) {
if (size == 0 || i >= size)
return nullptr;
SinglyLinkedNode<E>* currentNode = head;
for (unsigned int j = 0; j < i; j++)
currentNode = currentNode->nextNode;
return currentNode;
}
template <class E>
SinglyLinkedNode<E>* SinglyLinkedList<E>::getHeadNode() {
return head;
}
template <class E>
SinglyLinkedNode<E>* SinglyLinkedList<E>::getTailNode() {
return tail;
}
template <class E>
bool SinglyLinkedList<E>::contains(SinglyLinkedNode<E>* singlyLinkedNode) {
SinglyLinkedList<E>* currentNode = head;
while (currentNode != nullptr)
if (currentNode == singlyLinkedNode)
return true;
return false;
}
template <class E>
E SinglyLinkedList<E>::getDataAt(unsigned int i) {
SinglyLinkedNode<E>* singlyLinkedNode = getNodeAt(i);
if (singlyLinkedNode == nullptr)
throw 0;
return singlyLinkedNode->data;
}
template <class E>
E SinglyLinkedList<E>::getHeadData() {
if (head == nullptr)
throw 1;
return head->data;
}
template <class E>
E SinglyLinkedList<E>::getTailData() {
if (tail == nullptr)
throw 2;
return tail->data;
}
template <class E>
bool SinglyLinkedList<E>::contains(E data) {
if (size == 0)
return false;
SinglyLinkedNode<E>* currentNode = head;
while (currentNode != nullptr) {
if (currentNode->data == data)
return true;
currentNode = currentNode->nextNode;
}
return false;
}
template <class E>
E SinglyLinkedList<E>::remove(E data) {
if (size == 0)
throw 3;
if (head->data == data)
return removeHead();
if (size > 1) {
SinglyLinkedNode<E>* currentNode = head;
while (currentNode->nextNode != nullptr) {
if (currentNode->nextNode->data == data) {
E data = currentNode->nextNode->data;
SinglyLinkedNode<E>* nodeToDelete = currentNode->nextNode;
if (nodeToDelete == tail)
tail = currentNode;
currentNode->nextNode = currentNode->nextNode->nextNode;
delete(nodeToDelete);
size--;
return data;
}
currentNode = currentNode->nextNode;
}
}
throw 4;
}
template <class E>
E SinglyLinkedList<E>::removeAt(unsigned int i) {
if (size == 0 || i >= size)
throw 5;
if (i == 0)
return removeHead();
if (i == (size - 1))
return removeTail();
SinglyLinkedNode<E>* currentNode = head;
for (unsigned int j = 1; j < i; j++)
currentNode = currentNode->nextNode;
E data = currentNode->nextNode->data;
SinglyLinkedNode<E>* nodeToDelete = currentNode->nextNode;
currentNode->nextNode = currentNode->nextNode->nextNode;
delete(nodeToDelete);
size--;
return data;
}
template <class E>
E SinglyLinkedList<E>::removeHead() {
if (size == 0)
throw 6;
if (size == 1) {
E data = head->data;
delete(head);
size--;
head = nullptr;
tail = nullptr;
return data;
}
if (size == 2) {
E data = head->data;
SinglyLinkedNode<E>* newHead = head->nextNode;
delete(head);
head = newHead;
tail = newHead;
size--;
return data;
}
SinglyLinkedNode<E>* newHead = head->nextNode;
E data = head->data;
delete head;
head = newHead;
size--;
return data;
}
template <class E>
E SinglyLinkedList<E>::removeTail() {
if (size == 0)
throw 7;
if (size == 1)
return removeHead();
if (size == 2) {
E data = tail->data;
delete(tail);
tail = head;
size--;
return data;
}
SinglyLinkedNode<E>* currentNode = head;
while (currentNode->nextNode->nextNode != nullptr)
currentNode = currentNode->nextNode;
E data = tail->data;
delete(tail);
currentNode->nextNode = nullptr;
tail = currentNode;
size--;
return data;
}
template <class E>
void SinglyLinkedList<E>::clear() {
while (size > 0)
removeHead();
}
template <class E>
bool SinglyLinkedList<E>::isEmpty() {
if (size == 0)
return true;
}
template <class E>
unsigned int SinglyLinkedList<E>::getSize() {
return size;
}
template <class E>
SinglyLinkedList<E>::~SinglyLinkedList() {
clear();
}
The memory leak only asserts when I have more than one node in the list. I tried going step by step using the debugger, but everything seems to be working fine. Any leads would be very helpful.
At least in this function
template <class E>
SinglyLinkedNode<E>* SinglyLinkedList<E>::addToTail(E data) {
SinglyLinkedNode<E>* singlyLinkedNode = new SinglyLinkedNode<E>(data);
if (size == 0) {
head = singlyLinkedNode;
tail = singlyLinkedNode;
size++;
return singlyLinkedNode;
}
tail->nextNode = new SinglyLinkedNode<E>(data);
tail = tail->nextNode;
size++;
return singlyLinkedNode;
}
called by the function add
template <class E>
SinglyLinkedNode<E>* SinglyLinkedList<E>::add(E data) {
return addToTail(data);
}
there is a memory leak.
A new node is allocated twice when the list is not empty
SinglyLinkedNode<E>* singlyLinkedNode = new SinglyLinkedNode<E>(data);
and
tail->nextNode = new SinglyLinkedNode<E>(data);
And the allocated node pointed to by the pointer singlyLinkedNode is not deleted.
There is other problematic code in your program. For example the parameter of the assignment operator
void operator = (const SinglyLinkedList<E> singlyLinkedList);
should be a reference. Otherwise the operator will be inefficient because it will create a new temporary list.
And moreover it also produces numerous memory leaks because it does not clear the current list.
template <class E>
void SinglyLinkedList<E>::operator = (const SinglyLinkedList<E> singlyLinkedList) {
head = nullptr;
tail = nullptr;
size = 0;
SinglyLinkedNode<E>* currentNode = singlyLinkedList.head;
while (currentNode != nullptr) {
addToTail(currentNode->data);
currentNode = currentNode->nextNode;
}
}
You need to revise your entire program.:)
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
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?
I am having trouble implementing this with the class I have. So far as a linkedlist of type int or string it works great, but I am not sure how to navigate the list if I initialize it like
linkedlist<linkedlist<int>> nums;
From my program it seems that the head of each secondary list would be an entry in the primary, but my question is how would I navigate it?. For example how would I print all the values of each linkedlist, I am sure I am making this more difficult than it it, but any help would be appreciated.
/* Node Class */
template <typename T>
class Node {
public:
T data;
Node* next;
Node* previous;
Node(T data);
Node();
T getData();
};
template <typename T>
Node<T>::Node() {
this->next = NULL;
this->previous = NULL;
}
template <typename T>
Node<T>::Node(T data) {
this->data = data;
}
template <typename T>
T Node<T>::getData() {
return this->data;
}
/* Linked List: */
template <typename T>
class linkedlist {
private:
Node<T>* head;
Node<T>* tail;
int list_size;
public:
linkedlist();
T getHead();
T getTail();
int size();
void addnodetail(T);
void addnodehead(T);
void push(T);
T pop();
//T* peek();
bool isEmpty() const {
return head == NULL;
}
//T* get(int index);
void printlist();
void printListBackwards();
~linkedlist();
};
template <typename T>
linkedlist<T>::linkedlist() {
this->head = NULL;
this->tail = NULL;
this->list_size = 0;
}
template <typename T>
T linkedlist<T>::getHead() {
return this->head->data;
}
template <typename T>
T linkedlist<T>::getTail() {
return this->tail->data;
}
template <class T>
int linkedlist<T>::size() {
return this->list_size;
}
template <typename T>
void linkedlist<T>::addnodetail(T input) {
Node<T>* newnode = new Node<T>(input);
newnode->next = NULL;
newnode->previous = NULL;
if (this->head == NULL) {
this->head = newnode;
this->tail = this->head;
this->list_size = this->list_size + 1;
} else {
this->tail->next = newnode;
newnode->previous = this->tail;
this->tail = newnode;
this->list_size = this->list_size + 1;
}
}
template <typename T>
void linkedlist<T>::addnodehead(T input) {
Node<T>* newnode = new Node<T>(input);
newnode->next = NULL;
newnode->previous = NULL;
if (this->head == NULL) {
this->head = newnode;
this->tail = this->head;
this->list_size = this->list_size + 1;
} else {
this->head->previous = newnode;
newnode->next = this->head;
this->head = newnode;
this->list_size = this->list_size + 1;
}
}
template <typename T>
void linkedlist<T>::push(T input) {
this->addnodehead(input);
}
template <typename T>
T linkedlist<T>::pop() {
Node<T>* temp = this->head;
// T* temp = this->head;
this->head = this->head->next;
this->head->previous = NULL;
this->list_size = this->list_size - 1;
return temp->data;
}
/*
template <class T>
T* MyList<T>::peek() {
return this->head;
}
template <class T>
T* MyList<T>::get(int index) {
if (index == 0) {
return this->head;
} else if (index == this->list_size - 1) {
return this->tail;
} else if (index < 0 || index >= this->list_size) {
return NULL;
}
if (index < this->list_size / 2) {
T* temp = this->head;
int i = 0;
while (temp) {
if (i == index) { return temp; }
i++;
temp = temp->next;
}
} else {
T* temp = this->tail;
int i = this->list_size - 1;
while (temp) {
if (i == index) { return temp; }
i--;
temp = temp->previous;
}
}
return NULL;
}*/
template <typename T>
void linkedlist<T>::printlist() {
cout << "HEAD: ";
Node<T>* temp = this->head;
while(temp) {
cout << temp->data << " -> ";
temp = temp->next;
}
cout << "\b\b\b\b :TAIL" << endl;
}
template <class T>
void linkedlist<T>::printListBackwards() {
cout << "TAIL: ";
Node<T>* temp = this->tail;
while(temp) {
cout << temp->data << " -> ";
temp = temp->previous;
}
cout << "\b\b\b\b :HEAD" << endl;
}
template <typename T>
linkedlist<T>::~linkedlist() {
for(Node<T>* p;!isEmpty();){
p = head->next;
delete head;
head = p;
}
}
EDIT with copy constructor
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include <iostream>
#include <ctype.h>
using namespace std;
using namespace std;
/*struct AdjListNode
{
int dest;
struct AdjListNode* next;
};
// A structure to represent an adjacency list
struct AdjList
{
struct AdjListNode *head; // pointer to head node of list
};
// A structure to represent a graph. A graph is an array of adjacency lists.
// Size of array will be V (number of vertices in graph)
struct Graph
{
int V;
struct AdjList* array;
};
// A utility function to create a new adjacency list node
struct AdjListNode* newAdjListNode(int dest)
{
struct AdjListNode* newNode =
(struct AdjListNode*) malloc(sizeof(struct AdjListNode));
newNode->dest = dest;
newNode->next = NULL;
return newNode;
}
// A utility function that creates a graph of V vertices
struct Graph* createGraph(int V)
{
struct Graph* graph = (struct Graph*) malloc(sizeof(struct Graph));
graph->V = V;
// Create an array of adjacency lists. Size of array will be V
graph->array = (struct AdjList*) malloc(V * sizeof(struct AdjList));
// Initialize each adjacency list as empty by making head as NULL
int i;
for (i = 0; i < V; ++i)
graph->array[i].head = NULL;
return graph;
}
// Adds an edge to an undirected graph
void addEdge(struct Graph* graph, int src, int dest)
{
// Add an edge from src to dest. A new node is added to the adjacency
// list of src. The node is added at the begining
struct AdjListNode* newNode = newAdjListNode(dest);
newNode->next = graph->array[src].head;
graph->array[src].head = newNode;
// Since graph is undirected, add an edge from dest to src also
newNode = newAdjListNode(src);
newNode->next = graph->array[dest].head;
graph->array[dest].head = newNode;
}
// A utility function to print the adjacenncy list representation of graph
void printGraph(struct Graph* graph)
{
int v;
for (v = 0; v < graph->V; ++v)
{
struct AdjListNode* pCrawl = graph->array[v].head;
printf("\n Adjacency list of vertex %d\n head ", v);
while (pCrawl)
{
printf("-> %d", pCrawl->dest);
pCrawl = pCrawl->next;
}
printf("\n");
}
}
*/
/* Node Class */
template <typename T>
class Node {
public:
T data;
Node* next;
Node* previous;
Node(T data);
Node();
T getData();
};
template <typename T>
Node<T>::Node() {
this->next = NULL;
this->previous = NULL;
}
template <typename T>
Node<T>::Node(T data) {
this->data = data;
this->next = NULL;
}
template <typename T>
T Node<T>::getData() {
return this->data;
}
/* Linked List: */
template <typename T>
class linkedlist {
private:
Node<T>* head;
Node<T>* tail;
int list_size;
public:
linkedlist();
linkedlist(linkedlist& object);
T getHead();
T getTail();
int size();
void addtail(const T& input);
void addhead(const T& input);
void push(T);
T pop();
//T* peek();
bool isEmpty() const {
return head == NULL;
}
//T* get(int index);
void printlist();
void printListBackwards();
~linkedlist();
};
template <typename T>
linkedlist<T>::linkedlist() {
this->head = NULL;
this->tail = NULL;
this->list_size = 0;
}
template <typename T>
linkedlist<T>::linkedlist(linkedlist &object){
if(object.head == NULL){
head == NULL;
}
else {
head = new Node<T>(object.head->data);
Node<T>* temp = head;
Node<T>* objecthead = object.head;
Node<T>* current = objecthead;
while(current->next != NULL){
temp->next = new Node<T>(current->next->data);
current = current->next;
temp = temp->next;
}
}
}
template <typename T>
T linkedlist<T>::getHead() {
return this->head->data;
}
template <typename T>
T linkedlist<T>::getTail() {
return this->tail->data;
}
template <class T>
int linkedlist<T>::size() {
return this->list_size;
}
template <typename T>
void linkedlist<T>::addtail(const T& input) {
Node<T>* newnode = new Node<T>(input);
newnode->next = NULL;
newnode->previous = NULL;
if (this->head == NULL) {
this->head = newnode;
this->tail = this->head;
this->list_size = this->list_size + 1;
} else {
this->tail->next = newnode;
newnode->previous = this->tail;
this->tail = newnode;
this->list_size = this->list_size + 1;
}
}
template <typename T>
void linkedlist<T>::addhead(const T& input) {
Node<T>* newnode = new Node<T>(input);
newnode->next = NULL;
newnode->previous = NULL;
if (this->head == NULL) {
this->head = newnode;
this->tail = this->head;
this->list_size = this->list_size + 1;
} else {
this->head->previous = newnode;
newnode->next = this->head;
this->head = newnode;
this->list_size = this->list_size + 1;
}
}
template <typename T>
void linkedlist<T>::push(T input) {
this->addhead(input);
}
template <typename T>
T linkedlist<T>::pop() {
Node<T>* temp = this->head;
if(temp != NULL){
this->head = this->head->next;
this->head->previous = NULL;
this->list_size = this->list_size - 1;
return temp->data;
}
else{
cout << "Error:Empty List!";
exit (EXIT_FAILURE);
}
}
/*
template <class T>
T* MyList<T>::peek() {
return this->head;
}
template <class T>
T* MyList<T>::get(int index) {
if (index == 0) {
return this->head;
} else if (index == this->list_size - 1) {
return this->tail;
} else if (index < 0 || index >= this->list_size) {
return NULL;
}
if (index < this->list_size / 2) {
T* temp = this->head;
int i = 0;
while (temp) {
if (i == index) { return temp; }
i++;
temp = temp->next;
}
} else {
T* temp = this->tail;
int i = this->list_size - 1;
while (temp) {
if (i == index) { return temp; }
i--;
temp = temp->previous;
}
}
return NULL;
}*/
template <typename T>
void linkedlist<T>::printlist() {
cout << "STACK" << endl;
cout << "-------------------" << endl;
Node<T>* temp = this->head;
while(temp) {
cout << "\t" << temp->data << endl;
temp = temp->next;
}
//cout << "\b\b\b\b :TAIL" << endl;
}
template <class T>
void linkedlist<T>::printListBackwards() {
cout << "TAIL: ";
Node<T>* temp = this->tail;
while(temp) {
cout << temp->data << " -> ";
temp = temp->previous;
}
cout << "\b\b\b\b :HEAD" << endl;
}
template <typename T>
linkedlist<T>::~linkedlist() {
for(Node<T>* p;!isEmpty();){
p = head->next;
delete head;
head = p;
}
}
#endif // LINKEDLIST_H
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.