Adding nodes in a singly linked list using oop - c++

i have an assigment where i have to work with singly linked list using oop. I got stuck mostly on the sortedInsert function. I am assuming it will be some mistake with using pointers but I can't figure it out. And the program crashes after entering the user input in the for loop in initializeList function it might be because of the sortedInsert function but maybe it's something else.
Can someone help me figure out where am I getting it worng?
Here is the code:
#include <iostream>
using namespace std;
class Item{
private:
int m_value;
Item* m_next;
public:
Item(int val){
m_value = val;
m_next = NULL;
};
int getValue(){ return this->m_value; };
Item* getNext() { return this->m_next; };
void setValue(int val){ m_value = val; };
void setNext(Item* nxt){ m_next = nxt; };
};
class IntList{
private:
Item* m_front = NULL;
Item* m_end;
int m_size = 0;
void bump_up(int m_size){ m_size++; };
void bump_down(int m_size){ m_size--; };
public:
IntList(){ m_front = NULL; };
Item* getFirst(){ return this->m_front; };
//int getValueFirst(){ return this->firstItem->getValue(); };
~IntList();
void sortedInsert(Item* first, int val){
Item* newItem = new Item(val);
Item* current;
if(first == NULL || (first)->getValue() >= newItem->getValue()){
newItem->setNext(first);
first = newItem;
}
else{
current = first;
while(current->getNext() != NULL && current->getNext()->getValue() < newItem->getValue()){
current = current->getNext();
}
newItem->setNext(current->getNext());
current->setNext(newItem);
}
bump_up(m_size);
}
//print
void display(){
Item* p = m_front;
cout << "(" << m_size << ")";
while(p != NULL){
cout << p->getValue() << " ";
p = p->getNext();
}
cout << endl;
}
void initializeList(IntList* list){
int x, i;
cout << "Insert list size: ";
cin >> x;
cout << "Insert " << x << " numbers, which will be put in the list:";
for(i = 0; i <= x; i++){
int a;
cin >> a;
list->sortedInsert(list->getFirst(), a);
}
//cout << endl;
}
int main()
{
IntList* list = new IntList();
initializeList(list);
list->display();
return 0;
}

Related

Singly Linked List using Arrays: It's crashing on run-time

Whats wrong with this code?
I am writing this code to implement singly linked list using arrays but its not working. Im using code::blocks and its crashing on run time. Please help.
I must have missed out on something when it was taught in the class. xD
#include<iostream>
#include<stdio.h>
using namespace std;
class Node
{
int data;
Node *next;
public:
Node(int n)
{
data=n;
next=NULL;
}
friend class List;
};
class List
{
Node *listptr;
public:
void create();
void display();
};
void List::create()
{
Node *temp;
int n, num;
cout << "Enter number of nodes:" << endl;
cin >> n;
cout << "/nEnter the data" << endl;
for(int i=0; i<n; i++)
{
cin >> num;
Node *new_node=new Node(num);
if(listptr==NULL)
listptr=temp=new_node;
else
{
temp->next=new_node;
temp=temp->next;
}
}
}
void List::display()
{
Node *temp=listptr;
while(temp!=NULL)
{
cout << temp->data << "->";
temp=temp->next;
}
}
main()
{
List l1;
l1.create();
l1.display();
}
listptr not initialized, you can initialize in constructor.
List() {
listptr = 0;
}
Class List should be
class List
{
Node *listptr;
public:
List() {
listptr = 0;
}
void create();
void display();
};
Try following piece of code -
First Creating Node
class ListElement
{
int data;
ListElement* next;
public:
void set_element(int item) { data = item; }
int get_value() { return data; }
friend class List;
};
Another class for further operation
class List
{
ListElement *Start, *Tail, *New;
public:
List() { Start = Tail = New = NULL; } // initialise all pointer value to NULL
void add_element(int element) {
// Create a new Node
New = new ListElement;
New->set_element(element);
New->next = NULL;
// adding value or linkig each node to each other
(Start == NULL) ? Start = New : Tail->next = New;
Tail = New;
}
// print the whole linked list
void print()
{
ListElement* Current = Start;
while (Current != NULL)
{
cout << Current->get_value() << endl;
Current = Current->next;
}
}
};
Main Function
int main()
{
List L;
int num_of_element, element;
cin >> num_of_element;
for (int i(0); i < num_of_element; i++) {
cin >> element;
L.add_element(element);
}
L.print();
}
Hope it'll work.

Memory address instead of value in cout of class [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am trying to write own simple forward list implementation. I'd like to access element by cout << list[0]. I wrote the following code but instead of value I got something like x637c00539997. What did I do wrong?
What else can I improve in my code?
#include <iostream>
#include <assert.h>
#include <cstdio>
#include <cstring>
#include <memory>
using namespace std;
class myList{
public:
class myListExceptionEmpty: public exception
{
public:
virtual const char* what() const throw()
{
return "EMPTY";
}
};
void push_back(int valve);
int getSize();
bool isEmpty();
void removeFirst();
void remove(int x);
void dump();
void pop_front();
struct elem
{
std::shared_ptr<elem> next;
int val;
};
class proxy
{
public:
std::shared_ptr<myList::elem> position;
proxy(std::shared_ptr<myList::elem> pos)
{
position = pos;
}
};
std::shared_ptr<myList::proxy> operator[](int position);
private:
std::shared_ptr<elem> start;
std::shared_ptr<elem> getLastElement();
std::shared_ptr<proxy> current;
int size = 0;
};
ostream& operator<<(std::ostream& os, myList::proxy& obj)
{
os << obj.position->val;
return os;
}
shared_ptr<myList::proxy> myList::operator[](int position)
{
std::shared_ptr<elem> p = start;
for(int i=0;i<position;i++)
{
p = p->next;
if (p == NULL) throw std::out_of_range("out");
}
//cout << p->val;
std::shared_ptr<proxy> tmp(new myList::proxy(p));
current = tmp;
return current;
}
std::shared_ptr<myList::elem> myList::getLastElement()
{
std::shared_ptr<elem> p = start;
while(p->next != NULL ) p = p->next;
return p;
}
bool myList::isEmpty()
{
return size;
}
void myList::dump()
{
std::shared_ptr<elem> x = start;
while (x != NULL)
{
cout << x->val << endl;
x = x->next;
}
}
void myList::push_back(int valve)
{
std::shared_ptr<elem> p, n(new elem());
n->next = NULL;
n->val = valve;
p = start;
if(p != NULL)
{
while(p->next != NULL ) p = p->next;
p->next = n;
}
else start = n;
size++;
}
void myList::remove(int x)
{
if (size == 0) throw myListExceptionEmpty();
std::shared_ptr<elem> p, prv;
p = start;
while(p->next != NULL)
{
if (p->val == x)
{
prv->next = p->next;
size--;
}
prv = p;
p = p->next;
}
}
void myList::pop_front()
{
if (size == 0) throw myListExceptionEmpty();
std::shared_ptr<elem> p, prv;
p = start;
while(p->next != NULL)
{
prv = p;
p = p->next;
}
prv->next = NULL;
}
void myList::removeFirst()
{
if (size == 0) throw myListExceptionEmpty();
std::shared_ptr<elem> p;
p = start;
cout << start->val << endl;
if(p!= NULL)
{
start = p->next;
}
size--;
}
int myList::getSize()
{
return size;
}
int main()
{
myList array;
int size;
cin >> size;
char a;
int tmp;
for (int i=0; i<size; ++i) {
std::cin >> a;
if (a == 'D')
{
try{
array.removeFirst();
}
catch (myList::myListExceptionEmpty &e)
{
cout << e.what() << endl;
}
}
else if (a == 'A')
{
int tmp;
std::cin >> tmp;
array.push_back(tmp);
cout << "elem" << array[0];
}
else if (a == 'S') cout /*<< "Size:"*/ << array.getSize() << endl;
}
}
With regard to the question "what else to improve":
You're using shared pointers, great! Instead of using new use the corresponding routine make_shared (see C++ documentation).
Do not define classes in classes. Let each class have its own header and source file. It increases readability dramatically and even compiling gets faster by splitting all classes into different files (best way: use include guards). This way you can also leave the namespaces like myList::elem.
Use <cassert> instead of <assert.h>. You're using C++11 anyway, so why the need to use an old C-library?!
Just an example: Change void myList::remove(int x) to void myList::remove(const int& x). Let the compiler know that x is a read-only object. Do not call the int-copy constructor here (also at other code lines).
With regard to your 2nd question: your overloaded operator [] returns a shared-pointer and not the object this pointer is pointing at. Thus, it will print the address of the pointer.
This is program after fix. I used cout << *array[0]; instead of cout << array[0];. Than you for help
#include <iostream>
#include <memory>
using namespace std;
class MyListProxy;
class MyListExceptionEmpty: public exception
{
public:
virtual const char* what() const throw(){
return "EMPTY";
}
};
class MyList{
public:
void push_back(int valve);
int getSize() { return size; };
bool empty() { return size; };
void removeFirst();
void remove(const int& x);
void dump();
void pop_front();
void clear() {this->start = NULL; size = 0;}
struct elem
{
shared_ptr<elem> next;
int val;
};
shared_ptr<MyListProxy> operator[](int position);
private:
shared_ptr<elem> start;
shared_ptr<MyListProxy> current;
shared_ptr<elem> getEnd();
int size = 0;
};
class MyListProxy
{
public:
shared_ptr<MyList::elem> position;
MyListProxy(shared_ptr<MyList::elem> pos)
{
position = pos;
}
};
ostream& operator<<(ostream& os, MyListProxy& obj)
{
os << obj.position->val;
return os;
}
shared_ptr<MyListProxy> MyList::operator[](int position)
{
if (start == NULL) throw out_of_range("out");
shared_ptr<elem> p = start;
for(int i=0;i<position;i++){
p = p->next;
if (p == NULL) throw out_of_range("out");
}
return make_shared <MyListProxy>(p);
}
shared_ptr<MyList::elem> MyList::getEnd()
{
if (start == NULL) return start;
shared_ptr<elem> p = start;
while(p->next != NULL ) p = p->next;
return p->next;
}
void MyList::dump()
{
shared_ptr<elem> x = start;
while (x != NULL)
{
cout << x->val << endl;
x = x->next;
}
}
void MyList::push_back(int valve)
{
shared_ptr<elem> p;
auto last = this->getEnd();
auto a = make_shared<elem>();
last = a;
last->val = valve;
size++;
}
void MyList::remove(const int& x)
{
if (size == 0) throw MyListExceptionEmpty();
shared_ptr<elem> p, prv;
p = start;
while(p->next != NULL)
{
if (p->val == x)
{
prv->next = p->next;
size--;
}
prv = p;
p = p->next;
}
}
void MyList::pop_front()
{
if (size == 0) throw MyListExceptionEmpty();
start = start->next;
}
int main()
{
MyList array;
int size;
cin >> size;
char a;
int tmp;
for (int i=0; i<size; ++i) {
cin >> a;
if (a == 'D')
{
try{
cout << *array[0];
array.pop_front();
}
catch (MyListExceptionEmpty &e)
{
cout << "EMPTY" << endl;
}
catch (out_of_range &e)
{
cout << "EMPTY" << endl;
}
}
else if (a == 'A')
{
int tmp;
cin >> tmp;
array.push_back(tmp);
}
else if (a == 'S') cout /*<< "Size:"*/ << array.getSize() << endl;
cout << "SIZE::" << array.getSize() << endl;
}
}

How to create and execute a copy constructor for a linked list?

I have tried looking at videos and older posts but it is still very difficult to understand the concept of copy constructors. Would someone clear it up for me? My class did not really cover this part 100% my professor focused mainly on constructors and destructors.
Main CPP
#include <iostream>
#include "Header.h"
using namespace std;
int main()
{
node access;
access.getData();
access.outData();
system("pause");
return 0;
}
Header File
#include <iostream>
using namespace std;
class node
{
public:
node(); // Had to create my own default constructor because of my copy constructor.
node(const node &n); // This is a copy constructor.
~node();
void getData();
void outData();
private:
int num;
int lCount = 0; // Counts the number of nodes, increments after each user input.
int *ptr; // Where the linked list will be copied into
node *next;
node *first;
node *temp;
node *point;
};
node::node()
{
num = 0;
}
node::node(const node &n)
{
temp = first;
ptr = new node;
for (int i = 0; i < lCount; i++)
{
ptr[i] = temp->num;
temp = temp->next;
}
}
node::~node() // Deletes the linked list.
{
while (first != NULL)
{
node *delP = first; // Creates a pointer delP pointing to the first node.
first = first->next; // "Removes first node from the list and declares new first.
delete delP; // Deletes the node that was just removed.
}
cout << "List deleted" << endl;
}
void node::getData() // Simple function that creates a linked list with user input.
{
int input = 0;
point = new node;
first = point;
temp = point;
while (input != -1)
{
cout << "Enter any integer, -1 to end." << endl;
cin >> input;
if (input == -1)
{
point->next = NULL;
break;
}
else
{
lCount++;
point->num = input;
temp = new node;
point->next = temp;
point = temp;
}
}
}
void node::outData()
{
temp = first;
cout << "Original" << endl;
while (temp->next != NULL)
{
cout << temp->num << endl;
temp = temp->next;
}
cout << "Copied" << endl;
for (int i = 0; i < lCount; i++)
{
cout << ptr[i] << endl;
}
}
This little snippet is what I am having trouble with in particular:
node::node(const node &n)
{
temp = first;
ptr = new node;
for (int i = 0; i < lCount; i++)
{
ptr[i] = temp->num;
temp = temp->next;
}
}
I figured it out! I was tinkering with a much simpler copy constructor. I was having trouble understanding syntax, everything was very complicated and it was overwhelming to look at.
#include <iostream>
using namespace std;
class node
{
public:
node(int x); // Normal Construtor
node(const node &cpy); // Copy Constructor
void change(); // Changes data value
void outData();
private:
int data;
};
int main()
{
node var1(123);
var1.outData();
node var2 = var1;
var2.outData();
var2.change();
var1.outData();
var2.outData();
system("pause");
return 0;
}
node::node(int x)
{
data = x;
}
node::node(const node &cpy)
{
data = cpy.data;
}
void node::outData()
{
cout << data << endl;
}
void node::change()
{
int userIn;
cin >> userIn;
data = userIn;
}
Output:
123
123
(input: 4444)
Output:
123
4444

c++ : Expression must be a modifiable lvalue

I got
Expression must be a modifiable lvalue
in
rear->getNextNode() = &node;
Here is code:
using namespace std;
#include<iostream>
#include<string>
class Node
{
string name;
Node* next;
int arrivedTime;
int runningTime;
char state='R';
public:
Node(char* name,int arrivedTime,int runningTime):name(name),arrivedTime(arrivedTime),runningTime(runningTime){}
void printState()
{
cout << "name=" << name << " " << endl;
}
void execute()
{
runningTime--;
printState();
}
bool whetherArrive()
{
if (arrivedTime > 0)
{
return false;
}
else
{
return true;
}
}
void downArrivedTime()
{
arrivedTime--;
}
Node* getNextNode()
{
return next;
}
};
class Queue
{
public:
Node* head;
Node* rear;
Node* p;
void insert(Node &node)
{
if (head == NULL)
{
head = &node;
rear = &node;
p = &node;
}
else
{
rear->getNextNode() = &node; //here hint Expression must be a modifiable lvalue
}
}
};
int main()
{
cout << "input: process-count" << endl;
int processCount;
cin >> processCount;
for (int i = 0; i < processCount; i++)
{
cout << "input:process-name arrivedTime runningTime" << endl;
char name[20];
int arrivedTime;
int runningTime;
cin >> name >> arrivedTime >> runningTime;
Node node(name, arrivedTime, runningTime);
}
}
rear->getNextNode() return a pointer to Node, and then set the point &node. What's wrong here?
As in the error, to make this compile:
rear->getNextNode() = &node;
getNextNode() must return lvalue so you need to modify singature to:
Node*& getNextNode()
^

Can't add to linked list in switch

I tested my class member function to add to a linked list outside of my switch and it works. But when I try to use it in my switch, it doesn't. It won't actually add to the list cause when I display the list nothing is there.
Class and implementation:
#ifndef HEADER_H
#define HEADER_H
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
template <class T>
class LinkedList{
template<typename T>
class Node
{
public:
Node(T value = 0) : data(value), nextptr(NULL){};
T retrieve() const{ return data; }
Node<T> *next() const{ return nextptr; }
private:
T data;
Node<T> *nextptr;
friend LinkedList<T>;
};
public:
LinkedList();
LinkedList(const T& x); //Copy Constructor
~LinkedList();
void DisplayList();
void ReverseList();
LinkedList<T> operator= (const LinkedList<T> & x); //Assignment Operator
bool isEmpty() const{ return Size() == 0; }
int Size() const{ return n; }
bool ElementAt(int k, T& x) const;
LinkedList<T>& RemoveAt(int k, T& x)
{
if (k < 0 || k >= Size())
{
cout << "Index not in list.";
}
Node<T> *del = NULL;
if (k == 0)
{
del = list_head;
list_head = del->nextptr;
}
else
{
Node<T> *prev = list_head;
del = list_head->nextptr;
for (int i = 1; i< k; i++)
{
prev = del;
del = del->nextptr;
}
prev->nextptr = del->nextptr;
}
n--; x = del->data; delete del;
return *this;
}
LinkedList<T>& Add(const T& x)
{
Node<T>
*node = new Node<T>(x);
if (Size() == 0)
list_head = node;
else
{
Node<T> *temp = list_head;
while (temp->nextptr)
{
temp = temp->nextptr;
}
temp->nextptr = node;
}
n++;
return *this;
}
private:
Node<T> *list_head;
int n;
};
//Constructor
template<class T>
LinkedList<T>::LinkedList()
{
list_head = NULL;
n = 0;
}
//Copy Constructor
template<class T>
LinkedList<T>::LinkedList(const T& x)
{
list_head = x.listhead;
n = x.n;
}
//Destructor
template<class T>
LinkedList<T>::~LinkedList()
{
Node<T> *temp = list_head, *del, *nextptr;
while (temp != NULL)
{
del = temp->nextptr;
delete temp;
temp = del;
}
}
template<class T>
bool LinkedList<T>::ElementAt(int k, T& x) const
{
if (k < 0 || k >= Size())
return false;
Node<T> *temp = list_head;
for (int i = 0; i< k; i++)
{
temp = temp->next;
}
x = temp->data;
return true;
}
// Assignment Operator
template<class T>
LinkedList<T> LinkedList<T>::operator=(const LinkedList<T> & x)
{
list_head = x.list_head;
n = x.n;
return *this;
}
template<class T>
void LinkedList<T>::DisplayList()
{
Node<T> *temp = list_head;
while (temp != NULL)
{
cout << temp->data << endl;
temp = temp->nextptr;
}
}
template<class T>
void LinkedList<T>::ReverseList()
{
Node<T> *t, *y = list_head, *r = NULL, *listhead;
while (y != NULL)
{
t = y->nextptr;
y->nextptr = r;
r = y;
y = t;
}
list_head = r;
}
#endif
Driver:
#include "stdafx.h"
#include <iostream>
#include "Header.h"
using namespace std;
int main()
{
int choice;
string item;
do
{
LinkedList<string> list;
int num;
cout << "1. Add new record to the file" << endl;
cout << "2. Delete a record in the file (by index)" << endl;
cout << "3. Display entire list of items" << endl;
cout << "4. Display entire list of items backwards" << endl;
cout << "5. Exit" << endl;
cin >> choice;
switch (choice)
{
case 1:
{
cout << "1. Add new record to the file" << endl;
cout << "Enter the Item Description:" << endl;
cin.ignore();
getline(cin, item);
list.Add(item);
}
break;
case 2:
{
cout << "2. Delete a record in the file" << endl;
cout << "Enter the index number of the item you want to delete" << endl;
cin >> num;
//list.RemoveAt(num);
}
break;
case 3:
{
cout << "3. Display entire list of items" << endl;
list.DisplayList();
}
break;
case 4:
{
cout << "4. Display entire list of items backwards" << endl;
list.ReverseList();
list.DisplayList();
list.ReverseList();
}
break;
case 5:
{
return 0;
}
break;
}
} while (0 < choice < 6);
return 0;
}
Any ideas?
Move your list declaration outside of your do..while loop. At the moment it is being reinitialized each time round the loop.