Linked List Operations C++ - c++

I've got a linked list data base using templates which compiles fine and lets me print out a list of all states and lets me search for a person and print all that persons data (since these methods work, I left them out below to save space).
Below I have a print_people_in_state method, what I need to be able to do is to (given a user input of state) print out the info on all the people from that particular state. However right now when I run it, nothing happens. How can I fix this?
If you want to run the code yourself here is a link to the file that I named data.txt (http://rabbit.eng.miami.edu/class/een118/labs/152/dbfile1.txt)
#include <iostream>
#include <string>
#include <string.h>
#include <fstream>
using namespace std;
struct person
{
int dob,ss_number;
string fname, lname,state;
person()
{ }
person(int a, int b, string c, string d, string e)
{dob=a; ss_number=b; fname=c; lname=d; state=e;}
};
struct state
{
string sname;
person*P;
state()
{}
state(string a)
{sname=a;}
};
template<typename T>struct Link
{
T*data;
Link*extradata;
Link*next;
Link()
{}
Link(T*a,Link<T>*C=NULL)
{
data=a;
next=C;
}
};
template<typename T>
struct List
{int length;
Link<T>*Head,*tail;
List(Link<T>*h=NULL, Link<T>*t=NULL)
{
Head=h;
tail=t;
length=0;
}
void add(T*object)
{
{ if (Head == NULL && tail == NULL)
{ Link<T> * newlink = new Link<T>(object);
Head = newlink;
tail = Head; }
else
{ Link<T> * newlink = new Link<T>(object);
tail->next = newlink;
tail=newlink;} }
}
void print_people_in_state(string search)
{
Link<state>*temp=Head;
if(temp!==NULL)
{
if(temp->data->P->state==search)
{
cout<<temp->data->P->fname<<endl;
}
// temp=temp->next;
}}
};
List<person>*person_from_file(string file)//reads file
{
List<person>* newlist=new List<person>();
// Link<T> * head=NULL;
// Link<T> * temp=NULL;
ifstream fin;
fin.open("data.txt");
if (fin.fail())
cout<<"file not found\n";
if (!fin.fail())
{
while(true)
{
int a,b;
string c,d,e;
fin>>a>>b>>c>>d>>e;
if (fin.fail())break;
person * p=new person(a,b,c,d,e);
newlist->add(p);
}
}
else
cout<<"Can't open file";
fin.close();
return newlist;
}
List<state>*state_from_file(string file)//reads file
{
List<state>* newlist=new List<state>();
// Link<T> * head=NULL;
// Link<T> * temp=NULL;
ifstream fin;
fin.open("data.txt");
if (fin.fail())
cout<<"file not found\n";
if (!fin.fail())
{
while(true)
{
int a,b;
string c,d,e;
fin>>a>>b>>c>>d>>e;
if (fin.fail())break;
state * s=new state(e);
newlist->add(s);
}
}
else
cout<<"Can't open file";
fin.close();
return newlist;
}
int main()
{List<person>*A = person_from_file("data.txt");
List<state> *B= state_from_file("data.txt");
B->print_people_in_state("TX");
return 0;
}

You can simplify Link and List. You can read the file once and fill both lists at the same time. In fact, you don't really need a separate list for states, its usage is confusing.
template<typename T>class Link
{
public:
Link(T *data) { Data = data; Next = NULL; }
T *Data;
Link<T> *Next;
};
template<typename T>struct List
{
int Count;
Link<T> *Head, *Tail;
List() { Head = NULL; Tail = NULL; Count = 0; }
Link<T>* AddData(T *data)
{
Link<T> *node = new Link<T>(data);
Count++;
if (Head == NULL)
{
Head = Tail = node;
}
else
{
Tail->Next = node;
Tail = node;
}
return node;
}
};
int main()
{
List<person> *list = new List<person>;
ifstream fin("data.txt");
while (fin)
{
int a, b;
string c, d, e;
fin >> a >> b >> c >> d >> e;
list->AddData(new person(a, b, c, d, e));
}
Link<person> *node = list->Head;
while (node)
{
if (node->Data->state == "TX")
cout << node->Data->fname << endl;
node = node->Next;
}
return 0;
}

Related

Circular Single Linked List C++ Delete Problem

I want to remove one node from a Circular Single Linked List and when i reach to the Cmd, it shows me an address (maybe) which is repeating infintely. Please help me or show me what is wrong. Here is the code in C++
using namespace std;
class Node{
private:
int data;
Node * next;
public:
void setdata(int s);
int getdata()
{
return data;
}
void setnext(Node * next_pointer);
Node * getnext();
};
void Node::setdata(int s){
data = s;
}
Node * Node::getnext(){
return this->next;
}
void Node::setnext(Node *next_node)
{
this->next = next_node;
}
class Circular{
private:
Node * first;
int sizen;
public:
Circular();
void append(int value);
void display();
Node * walk(int start, int die=3);
int remove_node(Node * prev_node);
int getsize();
Node * get_first();
void removing(int val);
};
Circular::Circular(){
first = 0;
sizen = 0;
}
void Circular::append(int val)
{
Node * new_node = new Node;
new_node -> setdata(val);
if(this->sizen == 0 )
{
//There is empty
this->first = new_node;
this->first -> setnext(this->first);
this->sizen = 1;
}
else
{
//It's not empty
Node *node = this->first;
while(node->getnext()!= this->first)
{
node = node->getnext();
}
node->setnext(new_node);
node->getnext() -> setnext(this->first);
this->sizen +=1;
}
}
void Circular::display()
{
Node *temp = this->first;
std::cout<<temp->getdata()<<" ";
temp = temp->getnext();
while(temp!=this->first)
{
std::cout<<temp->getdata()<<" ";
temp = temp->getnext();
}
}
void Circular::removing(int val)
{
Node *new_node = this->first, *d;
/*if(new_node->sizen==0)
return 0;
if(new_node->sizen==1 && new_node->getdata() == val)
{free(new_node);
return 0;
}*/
std::cout<<"Removing "<<val<<std::endl;
while((new_node->getnext())->getdata()!=val)
{
new_node = new_node->getnext();
}
if((new_node->getnext())->getdata()==val)
{
d = new_node->getnext();
new_node->getnext() ->setnext(d->getnext());
free(d);
}
}
int Circular::getsize(){
Node *temp = this->first;
int length = 0;
length++;
while(temp->getnext()!=this->first)
{
temp = temp->getnext();
length++;
}
return length;
}
int main(){
Circular l;
int i, n,k;
std::cout<<"How many participants do you want? ";
std::cin>>n;
std::cout<<"Which participant should be killed? (Kth)";
std:cin>>k;
for(i=1;i<=n;i++)
l.append(i);
l.display();
l.removing(2);
l.display();
}
And Here is where the problem gets me anxious:
void Circular::removing(int val)
{
Node *new_node = this->first, *d;
/*if(new_node->sizen==0)
return 0;
if(new_node->sizen==1 && new_node->getdata() == val)
{free(new_node);
return 0;
}*/
std::cout<<"Removing "<<val<<std::endl;
while((new_node->getnext())->getdata()!=val)
{
new_node = new_node->getnext();
}
if((new_node->getnext())->getdata()==val)
{
d = new_node->getnext();
new_node->getnext() ->setnext(d->getnext());
free(d);
}
}
I have no error and when I run the program, I want to remove the Second (2) node, but it shows me:
1 1114304 1114304 1114304 1114304 1114304 and so on.

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.

Dot Product Calculation Link List Implementation

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

Cannot convert parameter 1 from Person to Person *[]

I'm trying to make program that reads from a file and adds to a binary tree, but when I try to compile I get an error:
"Error 1 'treePersons::display' : cannot convert parameter 1 from 'Node *' to 'Person *[]'"
The error appears in the call to display() in main()
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
struct Person{
int social;
int birthday;
string first;
string last;
string state;
double balance;
Person();
Person(int s, int b, string f, string l, string t, double a)
{
social = s;
birthday = b;
first = f;
last = l;
state = t;
balance = a;
}
};
struct Node{
Person data;
Node *left;
Node *right;
Node();
Node(Person x){
data = x;
left = NULL;
right = NULL;
}
};
class treePersons
{
protected:
public:
Node *root;
treePersons(){
root = NULL;
}
int fileName(Person *data[])
{
ifstream fin;
fin.open ("dbfile1.txt");
if (!fin.is_open())
cout << "File not found" << endl;
int i;
for(i = 0; i<100; i++)
while(fin.good())
{
fin >> data[i]->social >> data[i]->birthday >> data[i]->first >> data[i]->last >> data[i]->state >> data[i]->balance;
i++;
}
return i;
}
void add(Person *data[], Node*root)
{
int i = fileName(data);
if(root == NULL)
{
root = new Node();
}
for(int l = 0; l<i; l++)
{
if(data[i]->last == root->data.last)
{
if(data[i]->first != root->data.first)
{
if(data[i]->first < root->data.first)
{
add(data, root->left);
}
else if(data[i]->first > root->data.first)
{
add(data, root->right);
}
else if(data[i]->last == root->data.last && data[i]->first == root ->data.first)
{
cout << "already exists" << endl;
}
else if(data[i]->first < root->data.first)
{
add(data, root->left);
}
else if(data[i]->first > root->data.first)
{
add(data, root->right);
}
}
}
}
}
void printAlphabetically(Node *root)
{
if (root != NULL)
{
printAlphabetically(root->left);
cout << root->data.last << endl;
printAlphabetically(root->right);
}
return;
}
void display(Person *data[],Node *root)
{
add(data,root);
printAlphabetically(root);
};
};
struct State{
string state;
Person data;
State* left;
State * right;
State();
State(Person x)
{
data = x;
left = NULL;
right = NULL;
}
};
class treeState{
protected:
State *root;
public:
treeState()
{
root = NULL;
}
};
void main(){
treePersons T;
T.display(T.root->data,T.root);
}
It's very simple to see what's wrong with your code. You have the following:
treePersons T;
T.display(T.root->data, T.root);
Let's have a look at what a treePersons is:
class treePersons
{
Node *root;
...
};
It contains a single member: a Node. A Node is:
struct Node
{
Person data;
Node *left;
Node *right;
...
};
Your treePersons::display() function has the following signature:
void display(Person *data[], Node *root)
And you are passing a t.root->data (a Person) and t.root (a Node*)
The problem is you are attempting to pass a Person as a Person*[] which just isn't going to happen. There's no way to make that Person into a Person[], and you probably meant to make display take a Person* pointer, which will allow you pass a single Person or a container of Person: void display(Person* data, Node* root);
Of course, doing so will lead you down a big trail of problems as #R Sahu pointed out in the comments (most of your functions take a Person*[]. The solution here is to rethink what you are doing, and as #R Sahu suggests start much smaller and build up your program from there.
Consider also using std::vector when you need containers, and std::unique_ptr or std::shared_ptr where you require pointers (otherwise just use objects!). Also read (really read) the compiler output. It's telling you what the problem is, you just need to read.

Not able to output object in linked list

I have created a linked list and in each list consists a node that holds a CarPart object. I believe I have everything working, except outputting the cout. I get the following errors
'CarPart::getPartNumber': non-standard syntax; use '&' to create a pointer to member (carpart.cpp line 34)
'CarPart::getDescription': non-standard syntax; use '&' to create a pointer to member (carpart.cpp line 35)
'CarPart::getPrice': non-standard syntax; use '&' to create a pointer to member (carpart.cpp line 36)
I have tried changing the osstream operator and have not been able to figure out the issue.
Main.cpp
#include "stdafx.h"
#include "List.h"
int main()
{
List partsList;
partsList.push_front(new CarPart("FL2016", "Oil Filter", 18.95));
partsList.push_front(new CarPart("RS12YC", "Spark Plug", 4.15));
partsList.push_front(new CarPart("D5941", "Digital Tire Guage", 12.15));
partsList.push_back(new CarPart("G19216", "Car Wash Solution", 8.15));
partsList.display();
cout << "now we are going to remove the first item in the list" << endl;
system("PAUSE");
partsList.pop_front();
partsList.display();
system("PAUSE");
cout << "now we are going to remove the LAST item from the list" << endl;
partsList.pop_back();
partsList.display();
system("PAUSE");
return 0;
}
List.h
#pragma once
#include "node.h"
class List
{
private:
int listSize;
Node* n;
Node* temp;
Node* head;
Node* tail;
public:
List();
void push_front(CarPart*);
void push_back(CarPart*);
void pop_front();
void pop_back();
void display();
~List();
};
List.cpp
#include "stdafx.h"
#include "List.h"
List::List()
{
}
void List::push_front(CarPart* dat)
{
if (listSize == 0) {
n = new Node;
n->setData(dat);
listSize++;
temp = n;
head = n;
tail = n;
}
else {
n = new Node;
n->setData(dat);
listSize++;
temp = head;
head = n;
n->setNext(temp);
n->setPrevious(nullptr);
temp->setPrevious(n);
temp = n;
}
}
void List::push_back(CarPart* dat)
{
if (listSize == 0) {
n = new Node;
n->setData(dat);
listSize++;
temp = n;
head = n;
tail = n;
}
else {
n = new Node;
n->setData(dat);
listSize++;
temp = tail;
temp->setNext(n);
n->setPrevious(temp);
// SET NEXT TO NULL
temp = n;
tail = temp;
}
}
void List::pop_front()
{
temp = head->getNext();
delete head;
head = temp;
listSize--;
}
void List::pop_back()
{
temp = tail->getPrevious();
delete tail;
tail = temp;
tail->setNext(nullptr);
listSize--;
}
void List::display()
{
Node* test = head;
for (int i = 0; i < listSize; i++) {
cout << test;
}
}
List::~List()
{
}
Node.h
#pragma once
#include "CarPart.h"
class Node
{
private:
CarPart* data;
Node* next;
Node* previous;
public:
Node();
CarPart* getData();
void setData(CarPart*);
void setNext(Node*);
void setPrevious(Node*);
Node* getPrevious();
Node* getNext();
void display();
~Node();
};
Node.cpp
#include "stdafx.h"
#include "Node.h"
Node::Node()
{
}
CarPart* Node::getData()
{
return data;
}
void Node::setData(CarPart* dat)
{
data = dat;
}
void Node::setNext(Node* nextNode)
{
next = nextNode;
}
void Node::setPrevious(Node* prev)
{
previous = prev;
}
Node * Node::getPrevious()
{
return previous;
}
Node * Node::getNext()
{
return next;
}
void Node::display()
{
cout << data;
}
Node::~Node()
{
}
CarPart.h
#pragma once
#include <iostream>
using namespace std;
class CarPart
{
private:
string partNumber;
string description;
double price;
public:
CarPart();
CarPart(string, string, double);
string getPartNumber();
string getDescription();
double getPrice();
~CarPart();
friend ostream& operator<<(ostream& os, CarPart* dt);
};
CarPart.cpp
#include "stdafx.h"
#include "CarPart.h"
CarPart::CarPart()
{
}
CarPart::CarPart(string n, string d, double p)
{
partNumber = n;
description = d;
price = p;
}
string CarPart::getPartNumber()
{
return partNumber;
}
string CarPart::getDescription()
{
return description;
}
double CarPart::getPrice()
{
return price;
}
ostream& operator<<(ostream& os, CarPart* dt)
{
os << dt->getPartNumber;
os << dt->getDescription;
os << dt->getPrice;
return os;
}
CarPart::~CarPart()
{
}
Update
I fixed the error below, but it is not outputting the car parts, the console just shows 00820788008207880082078800820788. I assume it is just the pointer, but not sure what I am doing wrong.
You are calling your get functions incorrectly. You are using dt->getPartNumber; instead of using dt->getPartNumber();
To call a method/function, you always put brackets, even if there is no arguments (dt->getPartNumber()). This line
os << dt->getPartNumber()
means "pass to os the value returned by calling getPartNumber".
Otherwise, it interprets dt->getPartNumber as a pointer to the getPartNumber function, which is a very different beast.
NOTE: For future questions, try to post only the minimum code that causes the error instead of the entire program, and try to mark the line where the error is raised. Google for SSCCE.