In: Computer Science
Add a copy constructor for the linked list implementation below. Upload list.cpp with your code added. (DO NOT MODIFY THE HEADER FILE OR TEST FILE. only modify the list.cpp)
/*LIST.CPP : */
#include "list.h"
using namespace std;
// Node class implemenation
template <typename T>
Node<T>::Node(T element) { // Constructor
data = element;
previous = nullptr;
next = nullptr;
}
// List implementation
template <typename T>
List<T>::List() {
head = nullptr;
tail = nullptr;
}
template <typename T>
List<T>::List(const List& rhs) // Copy constructor -
homework
{
// Your code here
}
template <typename T>
List<T>::~List() { // Destructor
for(Node<T>* n = head; n != nullptr; n =
n->next) {
delete n;
}
}
template <typename T>
void List<T>::push_back(T element) {
Node<T>* new_node = new
Node<T>(element);
if (tail == nullptr) { // Empty list
head = new_node;
tail = new_node;
} else {
new_node->previous = tail;
tail->next = new_node;
tail = new_node;
}
}
template <typename T>
void List<T>::insert(Iterator<T> iter, T element)
{
if (iter.position == nullptr) {
push_back(element);
return;
}
Node<T>* after = iter.position;
Node<T>* before = after->previous;
Node<T>* new_node = new
Node<T>(element);
new_node->previous = before;
new_node->next = after;
after->previous = new_node;
if (before == nullptr) {
head = new_node;
} else {
before->next = new_node;
}
}
template <typename T>
Iterator<T> List<T>::erase(Iterator<T> iter)
{
Node<T>* remove = iter.position;
Node<T>* before = remove->previous;
Node<T>* after = remove->next;
if (remove == head) {
head = after;
} else {
before->next = after;
}
if (remove == tail) {
tail = before;
} else {
after->previous = before;
}
delete remove;
Iterator<T> r;
r.position = after;
r.container = this;
return r;
}
template <typename T>
Iterator<T> List<T>::begin() {
Iterator<T> iter;
iter.position = head;
iter.container = this;
return iter;
}
template <typename T>
Iterator<T> List<T>::end() {
Iterator<T> iter;
iter.position = nullptr;
iter.container = this;
return iter;
}
// Iterator implementation
template <typename T>
Iterator<T>::Iterator() {
position = nullptr;
container = nullptr;
}
template <typename T>
T Iterator<T>::get() const {
return position->data;
}
template <typename T>
void Iterator<T>::next() {
position = position->next;
}
template <typename T>
void Iterator<T>::previous() {
if (position == nullptr) {
position =
container->tail;
} else {
position =
position->previous;
}
}
template <typename T>
bool Iterator<T>::equals(Iterator<T> other) const
{
return position == other.position;
}
/*LIST.H :*/
// Doubly linked list
#ifndef LIST_H
#define LIST_H
template<typename T> class List;
template<typename T> class Iterator;
template <typename T>
class Node {
public:
Node(T element);
private:
T data;
Node* previous;
Node* next;
friend class List<T>;
friend class Iterator<T>;
};
template <typename T>
class List {
public:
List(); // Constructor
List(const List& rhs); // Copy
constructor - Homework
~List(); // Destructor
void push_back(T element); //
Inserts to back of list
void insert(Iterator<T> iter,
T element); // Insert after location pointed by iter
Iterator<T>
erase(Iterator<T> iter); // Delete from location pointed by
iter
Iterator<T> begin(); // Point
to beginning of list
Iterator<T> end(); // Point
to past end of list
private:
Node<T>* head;
Node<T>* tail;
friend class Iterator<T>;
};
template <typename T>
class Iterator {
public:
Iterator();
T get() const; // Get value pointed
to by iterator
void next(); // Advance iterator
forward
void previous(); // Advance
iterator backward
bool equals(Iterator<T>
other) const; // Compare values pointed to by two iterators
private:
Node<T>* position; // Node
pointed to by iterator
List<T>* container; // List
the iterator is used to iterattoe
friend class List<T>;
};
#endif
/*LIST TEST.CPP*/
// Test for templated linked list impementation
#include <iostream>
#include "list.h"
#include "list.cpp"
using namespace std;
int main() {
List<string> planets;
planets.push_back("Mercury");
planets.push_back("Venus");
planets.push_back("Earth");
planets.push_back("Mars");
for (auto p = planets.begin();
!p.equals(planets.end()); p.next())
cout << p.get() << "
";
cout << endl;
// Test erase
auto p = planets.begin();
// Erase earth
p.next(); p.next();
auto it = planets.erase(p);
cout << "Next in list: " << it.get()
<< endl;
// Test copy constructor - homework
List<string> planetsCopy(planets);
// Insert Earth into copy
p = planetsCopy.begin();
p.next();
planetsCopy.insert(p, "Earth");
// Print copied list - Should print: Mercury Earth
Venus Mars
for (auto p = planetsCopy.begin();
!p.equals(planetsCopy.end()); p.next())
cout << p.get() << "
";
cout << endl;
// Print original list - Should print: Mercury
Venus Mars
for (auto p = planets.begin();
!p.equals(planets.end()); p.next())
cout << p.get() << "
";
cout << endl;
}
template <typename T>
List<T>::List(const List &rhs) // Copy constructor - homework
{
Node<T> *p = rhs.head;
head = tail = NULL;
while (p != NULL)
{
this->push_back(p->data);
p = p->next;
}
}
PLEASE GIVE IT A THUMBS UP, I SERIOUSLY NEED ONE, IF YOU
NEED ANY MODIFICATION THEN LET ME KNOW, I WILL DO IT FOR
YOU
whole list.cpp file
#include "list.h"
using namespace std;
// Node class implemenation
template <typename T>
Node<T>::Node(T element)
{ // Constructor
data = element;
previous = nullptr;
next = nullptr;
}
// List implementation
template <typename T>
List<T>::List()
{
head = nullptr;
tail = nullptr;
}
// template <typename T>
// List<T>::List(const List &rhs) // Copy constructor - homework
// {
// // Your code here
// }
template <typename T>
List<T>::~List()
{ // Destructor
for (Node<T> *n = head; n != nullptr; n = n->next)
{
delete n;
}
}
template <typename T>
void List<T>::push_back(T element)
{
Node<T> *new_node = new Node<T>(element);
if (tail == nullptr)
{ // Empty list
head = new_node;
tail = new_node;
}
else
{
new_node->previous = tail;
tail->next = new_node;
tail = new_node;
}
}
template <typename T>
void List<T>::insert(Iterator<T> iter, T element)
{
if (iter.position == nullptr)
{
push_back(element);
return;
}
Node<T> *after = iter.position;
Node<T> *before = after->previous;
Node<T> *new_node = new Node<T>(element);
new_node->previous = before;
new_node->next = after;
after->previous = new_node;
if (before == nullptr)
{
head = new_node;
}
else
{
before->next = new_node;
}
}
template <typename T>
Iterator<T> List<T>::erase(Iterator<T> iter)
{
Node<T> *remove = iter.position;
Node<T> *before = remove->previous;
Node<T> *after = remove->next;
if (remove == head)
{
head = after;
}
else
{
before->next = after;
}
if (remove == tail)
{
tail = before;
}
else
{
after->previous = before;
}
delete remove;
Iterator<T> r;
r.position = after;
r.container = this;
return r;
}
template <typename T>
Iterator<T> List<T>::begin()
{
Iterator<T> iter;
iter.position = head;
iter.container = this;
return iter;
}
template <typename T>
Iterator<T> List<T>::end()
{
Iterator<T> iter;
iter.position = nullptr;
iter.container = this;
return iter;
}
// Iterator implementation
template <typename T>
Iterator<T>::Iterator()
{
position = nullptr;
container = nullptr;
}
template <typename T>
T Iterator<T>::get() const
{
return position->data;
}
template <typename T>
void Iterator<T>::next()
{
position = position->next;
}
template <typename T>
void Iterator<T>::previous()
{
if (position == nullptr)
{
position = container->tail;
}
else
{
position = position->previous;
}
}
template <typename T>
bool Iterator<T>::equals(Iterator<T> other) const
{
return position == other.position;
}
template <typename T>
List<T>::List(const List &rhs) // Copy constructor - homework
{
Node<T> *p = rhs.head;
head = tail = NULL;
while (p != NULL)
{
this->push_back(p->data);
p = p->next;
}
}