I have a member class, where I want to delete a node using id. I have created a struct for the linked list. all other functions are working properly, but I cannot delete the node at the given position. It works fine when i add member and when i show it, but when it comes to deleting node it does not work.
#include <iostream>
#include <string>
class member {
public:
struct nodetype {
int id;
string name;
string password;
string type;
nodetype* next;
};
member() {
start = NULL;
}
void addMember(int x, string n, string p, string t) {
nodetype* temp = new nodetype();
temp->id = x;
temp->name = n;
temp->password = p;
temp->type = t;
temp->next = start;
start = temp;
}
void showMember()
{
nodetype* temp = start;
while (temp != NULL)
{
cout << temp->id << "\t" << temp->name << "\t" << temp->type << "\t" << temp->password << endl;
temp = temp->next;
}
}
void deleteMember(int x)
{
nodetype* tmp = start;
while (tmp != NULL)
{
if (tmp->id == x)
{
nodetype* del = tmp;
start->next = tmp->next;
delete del;
}
}
}
private:
nodetype* start;
};
int main()
{
member obj;
obj.addMember(1,"joe","123","student");
obj.addMember(2,"john","456","staff");
obj.deleteMember(2);
obj.showMember();
}
First of all in deleteMember functionyou are not moving tmp forward.You can do it like-
void deleteMember(int x)
{
nodetype* tmp = start;
nodetype* prv = NULL;
while (tmp != NULL)
{
if (tmp->id == x)
{
if(prv != NULL)
{
prv->next=tmp->next;
}
else
{
start=tmp->next;
}
delete tmp;
break;
}
prv=tmp;
tmp=tmp->next;
}
}
Related
When I run my program, everything works as expected until the destructor of the LList class. On the line that says delete current;, I get the following error:
BlankConsoleLab.exe has triggered a breakpoint.
I have been trying to solve this issue for a long time. I would appreciate it if perhaps someone could try to point out what I am doing wrong here.
Below is my code for the program. Thank you
Linked List Class
class LList
{
private:
Node* head;
Node* tail;
int size = 0;
public:
LList()
{
head = nullptr;
tail = nullptr;
size = 0;
}
LList(Node* h, Node* t)
{
this->head = h;
this->tail = t;
}
~LList()
{
Node* current = head;
while (current != nullptr) {
Node* next = current->m_next;
delete current;
current = next;
}
}
void print()
{
//temporary node pointer to traverse through the linked list
Node* temp = head;
cout << endl << "<MY LINKED LIST>\n";
while (temp != nullptr)
{
cout << temp->m_data.firstName << " ";
cout << temp->m_data.lastName << " ";
cout << temp->m_data.hrWage << " ";
cout << temp->m_data.hrWork << " " << endl;
temp = temp->m_next;
}
cout << endl;
}
void removeFirst()
{
//case 1: linked list is empty (never enters loop)
//case 2: linked list is not empty
if (head != nullptr)
{
Node* temp = head;
head = head->m_next;
delete temp;
//decrease size tracker of the linked list
size--;
}
}
void removeLast()
{
//case 1: linked list is empty (never enters loop)
//case 2: linked list has one node
if (head->m_next == nullptr)
{
removeFirst();
}
//case 3: linked list has more than one node
else if (head != nullptr)
{
Node* cur = head;
Node* prev = nullptr;
while (cur->m_next != nullptr)
{
prev = cur;
cur = cur->m_next;
}
tail = prev;
tail->m_next = nullptr;
delete cur;
//decrease size tracker of the linked list
size--;
}
}
//void removeAt(int pos)
//{
// //Case 1: input is invalid (less than 1 or greater than size)
// if (pos < 1 && pos > size)
// {
// return;
// }
// //Case 2: input is position 1
// else if (pos == 1)
// {
// removeFirst();
// }
// //Case 3: input is the last position (input equals size)
// else if (pos == size)
// {
// removeLast();
// }
// //Case 4: input is valid, and not 1 or last position (greater than 1 and less than size)
// else if (head != nullptr)
// {
// Node* cur = head;
// Node* prev = nullptr;
// for (int i = 1; i < pos; i++)
// {
// prev = cur;
// cur = cur->m_next;
// }
// prev->m_next = cur->m_next;
// delete cur;
// size--;
// }
//}
Node* swap(Node* lh, Node* rh)
{
Node* temp = rh->m_next;
rh->m_next = lh;
lh->m_next = temp;
return rh;
}
void readBin()
{
ifstream file;
file.open("C:\\Users\\there\\source\\repos\\cst126-lab9-JEmersonLawrance\\BlankConsoleLab\\Employee Data.bin", ios::binary);
if (file)
{
Node* cur = head;
Node* prev = nullptr;
for (int i = 0; i < 4; i++)
{
file.read((char*)&cur->m_data.firstName, sizeof(cur->m_data.firstName));
file.read((char*)&cur->m_data.lastName, sizeof(cur->m_data.lastName));
file.read((char*)&cur->m_data.hrWage, sizeof(cur->m_data.hrWage));
file.read((char*)&cur->m_data.hrWork, sizeof(cur->m_data.hrWork));
prev = cur;
cur = cur->m_next;
}
return;
}
else
{
cout << "File could not be opened..\n" << endl;
}
file.close();
}
void writeBin()
{
ofstream file;
file.open("Employee Data Output.bin", ios::binary);
if (file)
{
Node* cur = head;
Node* prev = nullptr;
while (cur != nullptr)
{
file.write((char*)&cur->m_data.firstName, sizeof(cur->m_data.firstName));
file.write((char*)&cur->m_data.lastName, sizeof(cur->m_data.lastName));
file.write((char*)&cur->m_data.hrWage, sizeof(cur->m_data.hrWage));
file.write((char*)&cur->m_data.hrWork, sizeof(cur->m_data.hrWork));
prev = cur;
cur = cur->m_next;
}
}
else
{
cout << "File could not be opened..\n" << endl;
}
file.close();
}
};
Node Class
class Node
{
public:
Employee m_data;
Node* m_next;
Node()
{
m_data.firstName = "";
m_data.lastName = "";
m_data.hrWage = 0;
m_data.hrWork = 0;
m_next = nullptr;
}
Node(Node* next)
{
m_data.firstName = "";
m_data.lastName = "";
m_data.hrWage = 0;
m_data.hrWork = 0;
m_next = next;
}
Node(const Node& copy)
{
m_data.firstName = copy.m_data.firstName;
m_data.lastName = copy.m_data.lastName;
m_data.hrWage = copy.m_data.hrWage;
m_data.hrWork = copy.m_data.hrWork;
}
Node operator = (const Node& copy)
{
m_data.firstName = copy.m_data.firstName;
m_data.lastName = copy.m_data.lastName;
m_data.hrWage = copy.m_data.hrWage;
m_data.hrWork = copy.m_data.hrWork;
return *this;
}
~Node()
{
}
};
Employee Class
struct Employee
{
public:
string firstName;
string lastName;
int hrWage;
int hrWork;
Employee()
{
firstName = "";
lastName = "";
hrWage = 0;
hrWork = 0;
}
Employee(string first, string last, int wage, int work)
{
firstName = first;
lastName = last;
hrWage = wage;
hrWork = work;
}
~Employee()
{
}
void getInput()
{
for (int i = 0; i < 4; i++)
{
cout << "EMPLOYEE # " << i+1 << ":\n" << endl;
cout << "First name: ";
cin >> this[i].firstName;
cout << "Last name: ";
cin >> this[i].lastName;
cout << "Hourly Wage: ";
cin >> this[i].hrWage;
cout << "Hours Worked: ";
cin >> this[i].hrWork;
}
}
void writeBin()
{
ofstream file;
file.open("C:\\Users\\there\\source\\repos\\cst126-lab9-JEmersonLawrance\\BlankConsoleLab\\Employee Data.bin", ios::binary);
if (file)
{
for (int i = 0; i < 4; i++)
{
file.write((char*)&this[i].firstName, sizeof(this[i].firstName));
file.write((char*)&this[i].lastName, sizeof(this[i].lastName));
file.write((char*)&this[i].hrWage, sizeof(this[i]).hrWage);
file.write((char*)&this[i].hrWork, sizeof(this[i]).hrWork);
}
}
else
{
cout << "File could not be opened..\n" << endl;
}
file.close();
}
};
Main Function
int main()
{
cout << "In this program, LIST will read the user information"
<< " in from a binary file, and output it into a different binary"
<< " file.\n" << endl;
Employee data[4];
data->getInput();
data->writeBin();
//creating linked list
Node fourth;
Node third(&fourth);
Node second(&third);
Node first(&second);
LList LIST(&first, &fourth);
LIST.readBin();
LIST.writeBin();
LIST.print();
return 0;
}
In main(), you are constructing your LIST object with pointers to local Node objects that are created in automatic memory within main()'s call frame. When main() exits, all of its local variables are destroyed automatically. But, when the LIST object is destroyed, its destructor tries to call delete on those Node objects which were not created in dynamic memory with new. Thus, your code exhibits undefined behavior.
When I call the display function, the first element of linked list is printed twice. I do not know what is wrong with the code. Please help me to figure it out. The code is as follows:
#include <iostream>
using namespace std;
class node{
public:
char data;
node *link;
};
class linklist{
private:
node *start, *temp, *cur;
public:
linklist(){
start = NULL;
}
void insert(char x){
if (start == NULL){
start = new node;
start->data = x;
start->link = NULL;
cur = start;
}
else
while (cur->link != NULL){
cur = cur->link;
}
temp = new node;
temp->data = x;
temp->link = NULL;
cur->link = temp;
}
void display(){
cur = start;
while (cur->link != NULL){
cout << "Value is: " << cur->data << endl;
cur = cur->link;
}
cout << "Value is: " << cur->data << endl;
}
};
int main(){
linklist obj;
obj.insert('e');
obj.insert('t');
obj.insert('r');
obj.insert('w');
obj.insert('l');
obj.display();
system("Pause");
}
the expected output is: etrwl.
Actual output: eetrwl
You have two problems with your code. The first is the missing {...} surrounding your else statement in insert(). In order to have the needed code only apply to the else case, you need to surround the entire else case with braces, e.g.:
else {
while (cur->link != NULL) {
cur = cur->link;
}
temp = new node;
temp->data = x;
temp->link = NULL;
cur->link = temp;
}
}
Secondly, your conditional used for display() is incorrect. You only want to output the contents when cur != NULL not when cur->next != NULL (that is why you tried to tack an extra output statement following the end of the loop to catch your last value). Don't do that, if you find yourself trying to do something like that -- your are probably doing it wrong.
With that change, you simply have:
void display() {
cur = start;
while (cur != NULL) {
cout << "Value is: " << cur->data << endl;
cur = cur->link;
}
}
Putting it altogether, you have:
#include <iostream>
using namespace std;
class node{
public:
char data;
node *link;
};
class linklist{
private:
node *start, *temp, *cur;
public:
linklist() {
start = NULL;
}
void insert (char x) {
if (start == NULL) {
start = new node;
start->data = x;
start->link = NULL;
cur = start;
}
else {
while (cur->link != NULL) {
cur = cur->link;
}
temp = new node;
temp->data = x;
temp->link = NULL;
cur->link = temp;
}
}
void display() {
cur = start;
while (cur != NULL) {
cout << "Value is: " << cur->data << endl;
cur = cur->link;
}
}
};
int main (void) {
linklist obj;
obj.insert('e');
obj.insert('t');
obj.insert('r');
obj.insert('w');
obj.insert('l');
obj.display();
system("Pause");
}
Example Use/Output
$ ./bin/llinsert
Value is: e
Value is: t
Value is: r
Value is: w
Value is: l
Look things over an let me know if you have further questions.
#include <iostream>
#include <string>
using namespace std;
class Person{
public:
string name;
int age, height, weight;
Person(string name = "empty", int age = 0, int height = 0, int weight = 0) {
this->name = name;
this->age = age;
this->height = height;
this->weight = weight;
}
Person operator = (const Person &P) {
name = P.name;
age = P.age;
height = P.height;
weight = P.weight;
return *this;
}
void setAge(int a){
age = a;
}
int getAge(){
return age;
}
friend ostream& operator<<(ostream& os, const Person& p);
};
ostream& operator<<(ostream& os, Person& p) {
os << "Name: " << p.name << " " << "Age: " << p.age << " " << "Height: " << p.height << " " << "Weight: " << p.weight << "\n";
return os;
};
class Node {
public:
Person* data;
Node* next;
Node(Person*A) {
data = A;
next = nullptr;
}
};
class LinkedList {
public:
Node * head;
LinkedList() {
head = nullptr;
}
void InsertAtHead(Person*A) {
Node* node = new Node(A);
node->next = head;
head = node;
}
void InsertAtEnd(Person*A) {
if (head == nullptr) {
InsertAtHead(A);
}
else {
Node* node = new Node(A);
Node* temp = head;
while (temp->next != nullptr) {
temp = temp->next;
}
temp->next = node;
}
}
void InsertAtPosition(Person*A, int pos) {
if (head == nullptr) {
InsertAtHead(A);
}
else {
Node* node = new Node(A);
Node* temp = head;
for (int i = 1; i < pos - 1; i++) { temp = temp->next; }
node->next = temp->next;
temp->next = node;
}
}
void DeleteByValue(string search_name) {
Node* temp = head;
Node* prev = nullptr;
while (temp != nullptr) {
if (temp->data->name == search_name) {
if (prev != nullptr) {
prev->next = temp->next;
}
else {
head = temp->next;
}
delete temp;
temp = nullptr;
}
else {
prev = temp;
temp = temp->next;
}
}
}
void DeleteFromHead() {
if (head != nullptr) {
Node* temp = head;
head = head->next;
delete temp;
}
}
void DeleteFromEnd() {
Node* prev = nullptr;
Node* temp = head;
if (head == nullptr) { cout << "Nothing to delete" << endl; }
else if (head->next == nullptr) { DeleteFromHead(); }
else {
while (temp->next != nullptr) {
prev = temp;
temp = temp->next;
}
prev->next = nullptr;
delete temp;
}
}
void DeleteAtPosition(int pos) {
Node* prev = nullptr;
Node* temp = head;
if (head == nullptr) { cout << "Nothing to delete" << endl; }
else if (pos == 1) { DeleteFromHead(); }
else {
for (int i = 1; i < pos; i++) {
prev = temp;
temp = temp->next;
}
prev->next = temp->next;
delete temp;
}
}
void UpdateAtPosition(Person*A, int pos) {
if (head == nullptr) { cout << "No element in the list"; return; }
if (pos == 1) { head->data = A; }
else {
Node* temp = head;
for (int i = 1; i < pos; i++) {
temp = temp->next;
}
temp->data = A;
}
}
void UpdateByValue(string name, int newAge) {
Node* temp = head;
Person* p = new Person();
while(temp != nullptr){
if(temp->data->name == name){
p->setAge(newAge);
}else{
temp = temp->next;
}
}
}
void Print() {
Node* temp = head;
while (temp != nullptr) {
cout << *(temp->data);
temp = temp->next;
}
cout << endl;
}
};
int main() {
LinkedList* list = new LinkedList();
list->InsertAtHead(new Person("Samantha", 20, 63, 115)); list->Print();
list->InsertAtEnd(new Person("Chris", 19, 70, 200)); list->Print();
list->DeleteByValue("Chris"); list->Print();
list->UpdateByValue("Samantha", 21); list->Print();
return 0;
}
I am new to C++ so excuse any poorly written code, but I am trying to use the function UpdateByValue to update the age of Samantha. It may look very wrong right now, but I have tried 20 different things and cannot figure out what I am doing wrong. I used to go to school at a community college where I learned Java so Im catching up to everyone in C++. A lot of it is similar but I struggle with little things like this. Could anyone explain to me how to fix the UpdateByValue function so that it will change the age of my Person object of choice? I want to be able to type the name as the first parameter and change the age of that person with the second parameter. If something is unclear and needs more explaining please let me know, I just need help. Thanks in advance, and please feel free to give any other constructive criticism. I am trying to get as good as I can.
Let's take a walk through UpdateByValue. I'll comment as we go.
void UpdateByValue(string name, int newAge) {
Node* temp = head;
Person* p = new Person();
while(temp != nullptr){ // keep looking until end of list
if(temp->data->name == name){ // found node with name
p->setAge(newAge); // update a different node
// never advance node so we can't exit function
}else{
temp = temp->next;
}
}
}
Try instead
void UpdateByValue(string name, int newAge) {
Node* temp = head;
// Person * p is not needed
while(temp != nullptr){ // keep looking until end of list
if(temp->data->name == name){ // found node with name
temp->data->setAge(newAge); // update the found node
return; // done searching. Exit function
}else{
temp = temp->next;
}
}
}
I am trying to implement the a dot product calculation formula into the linked list implementation on my below code and I am having the below error:
request for member 'add_node' in 'B', which is of pointer type 'linked_list {aka node*}' (maybe you meant to use '->' ?)
How can I clear that and make working code? I don't want to use classes as well
#include <iostream>
#include <stdlib.h>
using namespace std;
struct node
{
int data;
int index;
node *next;
};
typedef node* linked_list;
node *head = NULL;
node *tail = NULL;
void add_node(int i,int n)
{
node *tmp = new node;
tmp->index = i;
tmp->data = n;
tmp->next = NULL;
if(head == NULL)
{
head = tmp;
tail = tmp;
}
else
{
tail->next = tmp;
tail = tail->next;
}
}
void display(node *head)
{
while(head!=0)
{
cout << head->index <<" ," << head->data << endl;
display(head->next);
break;
}
}
int main()
{
linked_list A;
A.add_node(2,7);
A.add_node(4,5);
A.add_node(7,8);
A.add_node(9,4);
linked_list B;
B.add_node(3,5);
B.add_node(4,6);
B.add_node(9,5);
int product=0;
while(A!=0 && B!=0)
{
if(A->index == B->index)
{
product = product + A->data * B->data;
A=A->next;
B=B->next;
}
else if(A->index < B->index)
{
A=A->next;
}
else
{
B=B->next;
}
}
return product;
return 0;
}
The error tells you what you need to know. linked_list is a pointer. You need to use the -> operator, not the dot operator.
Additionally, your node struct does not contain a method called add_node(). In fact it doesn't contain any methods at all.
#include <iostream>
using namespace std;
struct node
{
int data;
int index;
node *next;
};
class linked_list
{
private:
node *head,*tail;
public:
linked_list()
{
head = NULL;
tail = NULL;
}
void add_node(int i,int n)
{
node *tmp = new node;
tmp->index = i;
tmp->data = n;
tmp->next = NULL;
if(head == NULL)
{
head = tmp;
tail = tmp;
}
else
{
tail->next = tmp;
tail = tail->next;
}
}
node* gethead()
{
return head;
}
};
void display(node *head)
{
while(head!=0)
{
cout << head->index <<" ," << head->data << endl;
display(head->next);
break;
}
}
int main()
{
linked_list A;
A.add_node(2,7);
A.add_node(4,5);
A.add_node(7,8);
A.add_node(9,4);
linked_list B;
B.add_node(3,5);
B.add_node(4,6);
B.add_node(9,5);
display(A.gethead());
display(B.gethead());
int product=0;
node *current_a = A.gethead();
node *current_b = B.gethead();
while(current_a != 0 && current_b!=0)
{
if(current_a->index == current_b->index)
{
product = product + current_a->data * current_b->data;
current_a=current_a->next;
current_b=current_b->next;
}
else if(current_a->index < current_b->index)
{
current_a=current_a->next;
}
else
{
current_b=current_b->next;
}
}
cout<<"\nDot Product : "<< product<<endl;
return 0;
}
enter code here
When trying to add a new Node to the liked list it gives me a Segmentation fault. Can someone tell me what is wrong in the implementation of the addBook() function. I am not sure if it's the implementation of the function that is wrong, or the way that I've declared the classes.
class Reservation {
public:
int getID();
string getResevNum();
void setId(int x);
void setReseNum(string y);
private:
int ID;
string reservedNumber;
};
class ReservationCollection {
public:
ReservationCollection();
~ReservationCollection();
int getUserId(int &id);
string getUserBook(string &bookCall);
void findReservation();
void display();
void addBook(int id, string book);
void RemoveBook();
void ShutDown();
private:
struct Node {
Reservation *data;
Node *next;
};
Node *head;
};
ReservationCollection::ReservationCollection() {
Node *head = new Node;
head->next = NULL;
}
ReservationCollection::~ReservationCollection() {
}
void ReservationCollection::addBook(int id, string book){
Node *tmp = new Node;
tmp->data->setId(id);
tmp->data->setReseNum(book);
tmp->next = head->next;
head->next = tmp;
cout <<"Good\n";
}
int Reservation::getID(){
return ID;
}
string Reservation::getResevNum(){
return reservedNumber;
}
void Reservation::setId(int x){
ID = x;
}
void Reservation::setReseNum(string y){
reservedNumber = y;
}
int ReservationCollection::getUserId(int &id){
cout << "Enter Id number " << endl;
cin >> id;
return id;
}
string ReservationCollection::getUserBook(string &bookCall){
cout << "Enter book reservatin " << endl;
cin >> bookCall;
return bookCall;
}
int main()
{
int ID;
string BookNum;
char cmd;
do {
cout << "Enter command: ";
cin >> cmd;
ReservationCollection list;
if (cmd == 'A' || cmd == 'a'){
list.getUserId(ID);
list.getUserBook(BookNum);
list.addBook(ID, BookNum);
}
else if (cmd == 'S' || cmd == 's'){
cout << " list";
}
} while (cmd != 'Q' || cmd == 'q');
}
Wish I could just comment this:
All instances of the line Node *tmp = new Node; should read Node *tmp = new Node();
Don't use pointers if you don't have to. In this example Node has to be a pointer, because the list may have zero nodes, or 1000 nodes, so we need pointers to dynamically allocate memory on demand.
But (Reservation)data does not have to be a pointer. Each node always has one Reservation member.
If you do declare it as pointer then you must allocate it, and free it when it is no longer needed.
head should be initialized to NULL, because the single linked-list has no nodes when it is initialized. The first node inserted becomes the head.
#include <iostream>
#include <string>
using namespace std;
class Reservation
{
private:
int ID;
string reservedNumber;
public:
int getID() { return ID; }
string getResevNum() { return reservedNumber; }
void setId(int x) { ID = x; }
void setReseNum(string y) { reservedNumber = y; }
};
class ReservationCollection
{
public:
struct Node
{
Reservation data;
Node *next;
};
ReservationCollection();
~ReservationCollection();
void addBook(int id, string book);
Node* getHead() { return head; }
private:
Node *head;
};
ReservationCollection::ReservationCollection()
{
head = NULL;
}
ReservationCollection::~ReservationCollection()
{
Node *p = head;
while (p)
{
Node *next = p->next;
cout << "delete: " << p->data.getID() << ", " << p->data.getResevNum() << endl;
delete p;
p = next;
}
}
void ReservationCollection::addBook(int id, string book)
{
Node *node = new Node;
node->data.setId(id);
node->data.setReseNum(book);
//this element is the last element
node->next = NULL;
if (!head)
{
//first element inserted
head = node;
head->next = NULL;
}
else
{
//find the previous node in the list
Node *prev = head;
while (prev->next)
prev = prev->next;
//this node is after previous node
prev->next = node;
}
cout << "Good\n";
}
int main()
{
ReservationCollection list;
list.addBook(0, "Book0");
list.addBook(1, "Book1");
list.addBook(2, "Book2");
list.addBook(3, "Book3");
ReservationCollection::Node *p = list.getHead();
while (p)
{
ReservationCollection::Node *next = p->next;
cout << p->data.getID() << ", " << p->data.getResevNum() << endl;
p = next;
}
}
Creating a Node wont create the structure that Reservation *data; tries to point to, and so you try to access non initialized memory.
You need to initialize data:
tmp->data = new Reservation();