C++ format, if you can complete the extra credit functions that would be nice. B
ID: 3703854 • Letter: C
Question
C++ format, if you can complete the extra credit functions that would be nice. Below are the starter codes.
LList.h
#ifndef LLIST_H
#define LLIST_H
/*
Linked List class that store integers, with [] operator.
Uses head pointer.
*/
#include <ostream>
#include <stdexcept>
#define int int
using namespace std;
struct node_t {
int data;
node_t* next;
};
// This implementation will use a head pointer,
// allowing O(1) insertion on the front,
// and O(n) on the end.
class LList {
public:
LList(){
head = NULL;
}
~LList(){
clear();
}
LList(const LList& other){
// Do the same as the default constructor
head = NULL;
// Check if the other LList is empty
if(other.head == NULL){
return;
}
// Not empty? Iterate through the other list
// and push_back on myself.
node_t* temp = other.head;
while(temp){
push_back(temp->data);
temp = temp->next;
}
}
// Similar to copy constructor, but check for self
// assignment, if not, clear and copy all data.
LList& operator= (const LList& other){
if(this == &other){
return *this;
}
clear();
if(other.head == NULL){
return *this;
}
node_t* temp = other.head;
while(temp){
push_back(temp->data);
temp = temp->next;
}
return *this;
}
bool empty() const {
// TODO: Fill me in
}
unsigned int size() const {
// TODO: Fill me in
}
void push_back(int value){
// TODO: Fill me in
}
void push_front(int value){
// Empty list?
if(head == NULL){
head = new node_t;
head->data = value;
head->next = NULL;
}else{ // Not empty
node_t* temp = new node_t;
temp->data = value;
temp->next = head;
head = temp;
}
}
void pop_front(){
if(head == NULL) return;
node_t* temp = head;
head = head->next;
delete temp;
}
void pop_back(){
// TODO: Fill me in
}
// Overload [] operator
// Return logic error if index out of bounds
int& operator[](unsigned pos){
node_t* temp = head;
while(temp != NULL && pos > 0){
temp = temp->next;
pos--;
}
// As long as I don't have a null pointer, assign.
if(pos == 0 && temp != NULL){
return temp->data;
}
throw logic_error("Index invalid");
}
LList reverse() const {
// TODO: Fill me in
return LList(); // Remove me!
}
bool operator==(const LList& other) const {
}
bool operator!=(const LList& other) const {
return !operator==(other);
}
void clear(){
node_t* last = head;
while(head){
head = head->next;
delete last;
last = head;
}
// Normaly you never want to change head or you'll orphan part
// of the list, but in this case we are wiping the list,
// so it is ok to so and saves us a variable.
head = NULL;
}
private:
node_t* head;
};
// Note this function is O(n^2) because getAt is O(n) and we are
// doing it n times.
ostream& operator<<(ostream& out, const LList other){
out << "[";
for(unsigned int i = 1; i < other.size(); i++){
out << other.getAt(i-1) << ", ";
}
if(other.size() > 0){
out << other.getAt(other.size() - 1);
}
out << "]";
return out;
}
#endif
#ifndef LLIST_H
#define LLIST_H
/*
Linked List class that store integers, with [] operator.
Uses head pointer.
*/
#include <ostream>
#include <stdexcept>
#define int int
using namespace std;
struct node_t {
int data;
node_t* next;
};
// This implementation will use a head pointer,
// allowing O(1) insertion on the front,
// and O(n) on the end.
class LList {
public:
LList(){
head = NULL;
}
~LList(){
clear();
}
LList(const LList& other){
// Do the same as the default constructor
head = NULL;
// Check if the other LList is empty
if(other.head == NULL){
return;
}
// Not empty? Iterate through the other list
// and push_back on myself.
node_t* temp = other.head;
while(temp){
push_back(temp->data);
temp = temp->next;
}
}
// Similar to copy constructor, but check for self
// assignment, if not, clear and copy all data.
LList& operator= (const LList& other){
if(this == &other){
return *this;
}
clear();
if(other.head == NULL){
return *this;
}
node_t* temp = other.head;
while(temp){
push_back(temp->data);
temp = temp->next;
}
return *this;
}
bool empty() const {
// TODO: Fill me in
}
unsigned int size() const {
// TODO: Fill me in
}
void push_back(int value){
// TODO: Fill me in
}
void push_front(int value){
// Empty list?
if(head == NULL){
head = new node_t;
head->data = value;
head->next = NULL;
}else{ // Not empty
node_t* temp = new node_t;
temp->data = value;
temp->next = head;
head = temp;
}
}
void pop_front(){
if(head == NULL) return;
node_t* temp = head;
head = head->next;
delete temp;
}
void pop_back(){
// TODO: Fill me in
}
// Overload [] operator
// Return logic error if index out of bounds
int& operator[](unsigned pos){
node_t* temp = head;
while(temp != NULL && pos > 0){
temp = temp->next;
pos--;
}
// As long as I don't have a null pointer, assign.
if(pos == 0 && temp != NULL){
return temp->data;
}
throw logic_error("Index invalid");
}
LList reverse() const {
// TODO: Fill me in
return LList(); // Remove me!
}
bool operator==(const LList& other) const {
}
bool operator!=(const LList& other) const {
return !operator==(other);
}
void clear(){
node_t* last = head;
while(head){
head = head->next;
delete last;
last = head;
}
// Normaly you never want to change head or you'll orphan part
// of the list, but in this case we are wiping the list,
// so it is ok to so and saves us a variable.
head = NULL;
}
private:
node_t* head;
};
// Note this function is O(n^2) because getAt is O(n) and we are
// doing it n times.
ostream& operator<<(ostream& out, const LList other){
out << "[";
for(unsigned int i = 1; i < other.size(); i++){
out << other.getAt(i-1) << ", ";
}
if(other.size() > 0){
out << other.getAt(other.size() - 1);
}
out << "]";
return out;
}
#endif
list-sandbox.cpp
/*
Fill me in
*/
#include <iostream>
#include <vector>
#include "LList.h"
using namespace std;
int main(){
LList a;
for(int i = 0; i < 50; i++){
a.push_front(45);
}
return 0;
}
Explanation / Answer
Given below is the modified code for the question.
Please do rate the answer if it was helpful. Thank you
LList.h
=======
#ifndef LLIST_H
#define LLIST_H
/*
Linked List class that store integers, with [] operator.
Uses head pointer.
*/
#include <ostream>
#include <stdexcept>
#define int int
using namespace std;
struct node_t {
int data;
node_t* next;
};
// This implementation will use a head pointer,
// allowing O(1) insertion on the front,
// and O(n) on the end.
class LList {
public:
LList(){
head = NULL;
}
~LList(){
clear();
}
LList(const LList& other){
// Do the same as the default constructor
head = NULL;
// Check if the other LList is empty
if(other.head == NULL){
return;
}
// Not empty? Iterate through the other list
// and push_back on myself.
node_t* temp = other.head;
while(temp){
push_back(temp->data);
temp = temp->next;
}
}
// Similar to copy constructor, but check for self
// assignment, if not, clear and copy all data.
LList& operator= (const LList& other){
if(this == &other){
return *this;
}
clear();
if(other.head == NULL){
return *this;
}
node_t* temp = other.head;
while(temp){
push_back(temp->data);
temp = temp->next;
}
return *this;
}
bool empty() const {
return head == NULL;
}
unsigned int size() const {
node_t* temp = head;
int sz = 0;
while(temp != NULL)
{
sz++;
temp = temp->next;
}
return sz;
}
void push_back(int value){
node_t* n = new node_t;
n->data = value;
n->next = NULL;
if(head == NULL)
head = n;
else
{
node_t *last = head;
while(last->next != NULL)
last = last->next;
last->next = n;
}
}
void push_front(int value){
// Empty list?
if(head == NULL){
head = new node_t;
head->data = value;
head->next = NULL;
}else{ // Not empty
node_t* temp = new node_t;
temp->data = value;
temp->next = head;
head = temp;
}
}
void pop_front(){
if(head == NULL) return;
node_t* temp = head;
head = head->next;
delete temp;
}
void pop_back(){
node_t *prev2Last = NULL, *last = head;
if(empty())
return;
while(last->next != NULL)
{
prev2Last = last;
last = last->next;
}
if(prev2Last != NULL)
prev2Last->next = NULL;
else
head = NULL;
delete last;
}
// Overload [] operator
// Return logic error if index out of bounds
int& operator[](unsigned pos){
node_t* temp = head;
while(temp != NULL && pos > 0){
temp = temp->next;
pos--;
}
// As long as I don't have a null pointer, assign.
if(pos == 0 && temp != NULL){
return temp->data;
}
throw logic_error("Index invalid");
}
LList reverse() const {
node_t* temp = head;
LList rev;
while(temp != NULL)
{
rev.push_front(temp->data);
temp = temp->next;
}
return rev;
}
bool operator==(const LList& other) const {
node_t *n1 = head, *n2 = other.head;
while(n1 != NULL && n2 != NULL)
{
if(n1->data != n2->data)
return false;
n1 = n1->next;
n2 = n2->next;
}
if(n1 == NULL && n2 == NULL)
return true;
else
return false;
}
bool operator!=(const LList& other) const {
return !operator==(other);
}
int getAt(unsigned pos) const
{
node_t* temp = head;
while(temp != NULL && pos > 0){
temp = temp->next;
pos--;
}
// As long as I don't have a null pointer, assign.
if(pos == 0 && temp != NULL){
return temp->data;
}
throw logic_error("Index invalid");
}
void clear(){
node_t* last = head;
while(head){
head = head->next;
delete last;
last = head;
}
// Normaly you never want to change head or you'll orphan part
// of the list, but in this case we are wiping the list,
// so it is ok to so and saves us a variable.
head = NULL;
}
private:
node_t* head;
};
// Note this function is O(n^2) because getAt is O(n) and we are
// doing it n times.
ostream& operator<<(ostream& out, const LList &other){
out << "[";
for(unsigned int i = 1; i < other.size(); i++){
out << other.getAt(i-1) << ", ";
}
if(other.size() > 0){
out << other.getAt(other.size() - 1);
}
out << "]";
return out;
}
#endif
listsandbox.cpp
=========
#include <iostream>
#include <vector>
#include "LList.h"
using namespace std;
int main(){
LList a;
cout << "a.size() = " << a.size() << endl;
cout << "a.empty() = " << a.empty() << endl;
cout << "pushing to front 1 to 5 " << endl;
for(int i = 1; i <= 5; i++)
a.push_front(i);
cout << "list a: " << a << endl;
cout << "pushing to back 6 to 10 " << endl;
for(int i = 6; i <= 10; i++)
a.push_back(i);
cout << "list a: " << a << endl;
cout << "a.size() = " << a.size() << endl;
cout << "a.empty() = " << a.empty() << endl;
LList b = a;
cout << "list b: " << b << endl;
if(a == b)
cout << "list a and b are equal" << endl;
else
cout << "list a and b are NOT equal" << endl;
LList c = a.reverse();
cout << "list c = reverse of a: " << c << endl;
if(a != c)
cout << "list a and c are NOT equal" << endl;
else
cout << "list a and c are equal" << endl;
cout << "adding 2 to each element of list c, using [] operator" << endl;
for(int i = 0 ; i< c.size(); i++)
c[i] = c[i] + 2;
cout << "list c: " << c << endl;
cout << "popping back all elements in list c" << endl;
while(!c.empty())
c.pop_back();
cout << "list c: " << c << endl;
return 0;
}
output
======
a.size() = 0
a.empty() = 1
pushing to front 1 to 5
list a: [5, 4, 3, 2, 1]
pushing to back 6 to 10
list a: [5, 4, 3, 2, 1, 6, 7, 8, 9, 10]
a.size() = 10
a.empty() = 0
list b: [5, 4, 3, 2, 1, 6, 7, 8, 9, 10]
list a and b are equal
list c = reverse of a: [10, 9, 8, 7, 6, 1, 2, 3, 4, 5]
list a and c are NOT equal
adding 2 to each element of list c, using [] operator
list c: [12, 11, 10, 9, 8, 3, 4, 5, 6, 7]
popping back all elements in list c
list c: []
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.