Linked Lists not properly displaying - c++

I have created a linked list that each node holds a CarPart object. I know that the issue is that I am not properly de-referencing the pointer and it just displays the pointer and not the actual value... problem being is I have not been able to figure out how properly display the car part items to the console.
Per request I have removed any code that does not effect the outcome of what I am trying to do.
Main.cpp
#include "stdafx.h"
#include "List.h"
int main()
{
/*cout << new Node(new CarPart("Hello", "World", 99.00));*/
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::display()
{
Node* test = head;
for (int i = 0; i < listSize; i++) {
cout << test;
}
}
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()
{
}
void Node::display()
{
cout << data;
}
CarPart.h
#pragma once
#include <iostream>
#include <string>
using namespace std;
class CarPart
{
private:
string partNumber;
string description;
double price;
public:
CarPart();
CarPart(string, string, double);
string getPartNumber();
string getDescription();
double getPrice();
void display();
~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() << endl << dt->getDescription() << endl << dt->getPrice() << endl;
return os;
}

There are multiple problems with your code, but they all share the same root problem, so I'll just explain the first one, and after figuring out how to fix it you should be able to fix the rest of them by yourself:
void List::display()
{
Node* test = head;
for (int i = 0; i < listSize; i++) {
cout << test;
}
}
As you've observed, all this does is print the value of the pointer. Examining the contents of your header files, it appears that your class Node has a method called display().
You did now show the display() method, but given what I see in List::display(), it's reasonable to expect that Node::display()'s purpose would be similar, so you probably meant to do this, instead:
void List::display()
{
Node* test = head;
for (int i = 0; i < listSize; i++) {
test->display();
}
}
But this is not right, either. All this will accomplish is invoke your head Node's display() method over and over again. If your List has five Nodes, you'll get the contents of the first Node display()ed five times. You simply need to change this loop to walk through the link list, instead.
Now, your Node::display() method has the same problem as above, but now you should be able to fix it yourself.

Related

C++Linked list non-member function to reverse print

So I understood how to print a single linked list in reverse order using recursion. I'm having trouble with doing it non member functions.
For example in int print_reverse(IntSLList & list)) function how do you print reverse in an iterative way?
************************ .h file **************************
class IntSLLNode {
public:
IntSLLNode() {
next = 0;
}
IntSLLNode(int el, IntSLLNode *ptr = 0) {
info = el; next = ptr;
}
int info;
IntSLLNode *next;
};
class IntSLList {
public:
IntSLList() {
head = 0;
}
~IntSLList();
int isEmpty() {
return head == 0;
}
void addToHead(int);
void addToTail(int);
int deleteFromHead(); // delete the head and return its info;
int deleteFromTail(); // delete the tail and return its info;
bool isInList(int) const;
void printAll() const;
private:
IntSLLNode *head;
};
and here is the main
************************ main **************************
#include <iostream>
using namespace std;
#include "intSLList.h"
int print_reverse(IntSLList & list){
if (head == NULL)
return;
printReverse(head->next);
cout << head->data << " ";
//How to compelete this in an iterative(or recursive if iterative is too much work)way ?
//like this?
}
int main() {
IntSLList list;
list.print_reverse(list);
}
Added the functions
The header gives literally no way to access the contents of the list, other than by destroying it. So ... that's what we're going to do.
int deleteFromTail(); // delete the tail and return its info;
Except we need to go the extra step and rebuild it, because nobody expects printing the container to destory its contents. See https://en.wikipedia.org/wiki/Principle_of_least_astonishment
#include <iostream>
#include <stack>
#include <list>
class IntSLList {
public:
int isEmpty() { return m_list.empty(); }
void addToHead(int i) { m_list.push_front(i); }
void addToTail(int i) { m_list.push_back(i); }
int deleteFromHead() {
int temp = m_list.front();
m_list.pop_front();
return temp;
}
int deleteFromTail() {
int temp = m_list.back();
m_list.pop_back();
return temp;
}
private:
// no implementation given so I'm using std::list internally.
std::list<int> m_list;
};
int print_reverse(IntSLList& mylist) {
// store the data we are destroying in temp
IntSLList temp;
// literally the only way we can access the contents of the container is destructive so ... guess we're going there
while (!mylist.isEmpty()) {
int back = mylist.deleteFromTail();
std::cout << back << std::endl;
temp.addToHead(back);
}
// now rebuild the original list. I told you this would be bad.
while (!temp.isEmpty()) {
mylist.addToHead(temp.deleteFromTail());
}
// maybe this was supposed to be length, but not documented so I can return whatever I want.
return -1;
}
int main() {
IntSLList mylist;
mylist.addToTail(1);
mylist.addToTail(2);
mylist.addToTail(3);
print_reverse(mylist);
}
3
2
1

nodes are being added at some unknown locations in my binary search tree

To learn implementation of binary search tree,
I created a class bst and am facing problem in its add_node_private function.
bst.cpp -
#include <iostream>
#include <cstdlib>
using namespace std;
#include "bst.h"
// bst constructor
bst::bst() {
root = nullptr;
}
// methods of binary search tree
bst::node* bst::create_leaf(int a) { // creating a leaf with key
node* leaf = new node;
leaf->key = a;
leaf->left = nullptr;
leaf->right = nullptr;
return leaf;
}
// adding a leaf to the tree
void bst::add_leaf(int k) {
bst::add_leaf_private(k, root); // just calls the private function
// providing it with root
}
void bst::add_leaf_private(int k, node* ptr) {
if (ptr == nullptr) {
ptr = create_leaf(k);
cout << k << " added\n";
return;
}
if (k > ptr->key) {
cout << "went left of " << ptr->key << endl;
add_leaf_private(k, ptr->right);
}
if (k < ptr->key) {
cout << "went right of " << ptr->key << endl;
add_leaf_private(k, ptr->left);
}
if (k == ptr->key) {
cout << "key " << k << " already exists\n";
}
}
bst.h
#ifndef _BST_H
#define _BST_H
class bst
{
private:
struct node{
int key;
node* left;
node* right;
};
//private methods
void add_leaf_private(int k,node* ptr);
//void print_private(node* ptr);
public:
node* root=nullptr;
//bst constructor
bst();
//public methods
node* create_leaf(int k);
void add_leaf(int k);
//void print();
};
#endif // _BST_H
When I add leaves, I output shows that they were added (like this- 5 added)
main.cpp
#include <iostream>
#include <cstdlib>
#include "bst.h"
using namespace std;
int main(){
bst b1;
int tree_keys[]{50,70,21,4,32,64,15,51,14,100,83,2,3,70,87,90};
for(int x: tree_keys){
b1.add_leaf(x);
}
cout<<"root"<<b1.root<<endl;
return 0;
}
But I don't see any statement went left of ... or went right of ... which I was expecting. And later I checked and found out even after adding a bunch of nodes, I have my root==nullptr and I don't know where the nodes were being added then?
you are never updating root. Its always nullptr
you need
void bst::add_leaf_private(int k, node* ptr) {
if (ptr == nullptr) {
ptr = create_leaf(k);
root = ptr;
cout << k << " added\n";
return;
}
I made a stupid mistake of using ptr in the function add_leaf_private by value. I should have passed it by reference as I intend to change it in the function. Replacing ptr with &ptr solved the problem.

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.

Search engine using binary tree code c++ help please

I am doing a project about search engine usinng binary tree.
I think there are a lot of problems. I tried so mush without any result
and I don't know how to call Btree in main, it gives me an error all the time.
I have a text file with int and string. It will be like this:
1925 John Baird transmits the first television signal
In this program I will search by the int year and give the information of what happend in that year.
1-information class
#include <iostream>
#include <string>
using
namespace std;
class information{
private:
int year;
string data;
public:
information(int year, string data);
string getData();
int getyear();
void setData(string dat);
void setYear(int yer);
};
2- BinNode class
#include "information.h"
#include <iostream>
// Binary tree node ADT
template <typename Elem> class BinNode {
public:
virtual ˜BinNode() {}
virtual void setEvent(const information&) = 0;
virtual BinNode* left() const = 0;
virtual void setLeft(BinNode*) = 0;
virtual BinNode* right() const = 0;
virtual void setRight(BinNode*) = 0;
virtual bool isLeaf() = 0;
};
3-BNode class
#include <iostream>
#include "BinNode.h"
#include "information.h"
using namespace std;
// Binary tree node implementation
template <typename Elem>
class BNode: public BinNode<Elem> {
private:
information Event;
BNode* lc;
BNode* rc;
public:
BNode() { lc=rc=NULL;}
BNode(information d, Bnode* l = NULL,
Bnode* r = NULL) {
info = d; lc = l; rc = r;
}
information getEvent(){
return information.getEvent;
}
information setEvent(information e) {
Event = e;
}
BNode* left() const {return lc;}
void setLeft(BNode* b) {lc = b;}
BNode* right() const {return rc;}
a
void setRight(BNode* b) {rc = b}
bool isLeaf() {
return (lc==NULL) && (rc==NULL);
}
};
4- BinaryTree class
#include <iostream>;
// Binary tree ADT
template <int> class BinaryTree {
public:
BinaryTree();
virtual bool search() =0;
virtual bool search() =0;
virtual void insert() =0;
virtual bool remove() = 0;
virtual void fillTree() = 0
};
5- BTree class
#include <iostream>
#include<fstream>
#include "BinaryTree.h"
#include "BNode.h"
#include "information.h"
using namespace std;
// Binary tree implementation
template <type Elem> class BTree: public BinaryTree<Elem> {
private:
BNode* root;
public:
BinaryTree() {root = NULL;}
void insert(information i){
BNode* current;
BNode* trailCurrent;
BNode* newNode;
newNode = new BNode;
newNode->Event= i;
newNode->lc=NULL; newNode->rc=NULL;
if (root == NULL)
root = newNode;
else{
current = root;
while(current!=NULL){
trailCurrent = current;
if (current->Event== i){
cout<< “No duplicate allowed”;return;}
else if (current->Event> key)
current = current->lc;
else current = current->rc;
}
if(trailCurrent->Event> i)
trailCurrent->lc = newNode;
else trailCurrent->rc = newNode;
}
}
bool search(int key){
Bnode* current;
bool found = false;
if (root == NULL)
cout << "Empty Tree";
else{
current = root;
while(current!= NULL && !found){
if (current->Event.getYear() == key)
found = true;
cout << "The IN FORMATION for " << key << " is " << curr->Event.getData() << endl;
else if (current->Event> key)
current = current->lc;
else current = current->rc;
}
}
}
bool remove(information i){
BNode* current;
BNode* newNode;
newNode = new BNode;
newNode->Event= i;
newNode->lc=NULL; newNode->rc=NULL;
current = root;
while(current!=NULL){
if (current->Event== i){
delete current;
}
}
}
};
6- main
#include <iostream>
#include "BTree.h"
#include "information.h"
#include <fstream>
#include<string>
using namespace std;
int main(){
BTree <> b;
int ch;
string data;
int key,key2;
int year;
ifstream file;
file.open("date.txt");
if(!file) {
cout<<" Error opening file. " << endl;
}
while(file >> year >> data)
{
year = file.get();
p.setYear(year);
cout << p.getyear() << " ";
getline ( file, data );
p.setData(data);
cout << p.getData() << endl;
b.insert(p);
}
file.close();
while(1)
{
cout<<" Binary Search Tree"<<endl;
cout<<" 0. Search by year"<<endl;
cout<<" 1. Search by tow year "<<endl;
cout<<" 2. Exit "<<endl;
cout<<" Enter your choice : ";
cin>>ch;
switch(ch)
{
case 0 : cout <<" Enter the year to search : "<<endl;
cin>>key;
b.search(key);
break;
case 1 : cout<<" Enter the first year: ";
cin>>key;
cout<<" Enter the socend year: ";
cin>>key2;
// b.search(key,key2);
break;
case 2 : return 0;
}
}
};
I can see a problem, The Btree class is reinitalizing the constructor to BinaryTree
It should be:
public:
//BinaryTree() {root = NULL;}
Btree() { }
The Derived class, by principle will call Base classes constructor.
Another one:
virtual bool search() =0;
is being declared twice.
Another one:
virtual void fillTree() = 0;
Requires you to define a fillTree function in your Btree(Derived) class. Or have it as an absolute virtual function in the Derived class, but then that means the class must not be initiated, and should Inherited by another Dervied class which defines the virtual function.
This link might help

Read integers into a simple linked list from text file. Then bubblesort the list of integers and read out to another file

Read integers into a simple linked list from text file. Then bubblesort the list of integers and read out to another file. Right now I am reading into the main but I am trying to overload the extraction operator to read it in and I am not sure how to go about that. My Bubblesort function is also causing alot of issues. Its telling me the function cannot be overloaded and the node identifier is undeclared amongst other things. Any help would be greatly appreciated
Main file
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <fstream>
#include "bubble.h"
using namespace std;
struct nodeType
{
int info;
nodeType* link;
};
node *head_ptr = NULL;
void Display();
void list_clear(nodeType*& head_ptr);
void list_copy(const nodeType* source_ptr, nodeType*&head_ptr, nodeType*&tail_ptr);
Bubblesort();
int main()
{
ifstream datld;
ofstream outld;
Bubble D3;
datld.open ("infile2.txt");
if (!datld)
{
cout << "failure to open data.txt" << endl;
system ("pause");
return 1;
}
datld >> D3;
while(datld)
{
cout << D3<< endl;
datld >> D3;
}
system("pause");
return 0;
Bubblesort();
}
void Bubblesort()
{
node* curr = head_ptr;
int count = 0;
while(curr!=NULL)
{
count++;
curr = curr->NEXT;
}
for(int i = count ; i > 1 ; i-- )
{
node *temp, *swap1;
swap1 = HEAD;
for(int j = 0 ; j < count-1 ; j++ )
{
if(swap1->DATA > swap1->NEXT->DATA)
{
node *swap2 = swap1->NEXT;
swap1->NEXT = swap2->NEXT;
swap2->NEXT = swap1;
if(swap1 == HEAD)
{
HEAD = swap2;
swap1 = swap2;
}
else
{
swap1 = swap2;
temp->NEXT = swap2;
}
}
temp = swap1;
swap1 = swap1->NEXT;
}
}
}
void list_clear(nodeType*& head_ptr)
//Library facilities used:cstdlib
{
nodeType * removeptr;
while(head_ptr!=NULL)
{
removeptr=head_ptr;
head_ptr=head_ptr->link;
delete removeptr;
}
}
void list_copy(const nodeType* source_ptr, nodeType*&head_ptr, nodeType*&tail_ptr)
{
nodeType* temp;// to allocate new nodes
head_ptr=NULL;
tail_ptr=NULL;
if(source_ptr==NULL)
return;
head_ptr=new nodeType;
head_ptr->link=NULL;
head_ptr->info=source_ptr->info;
tail_ptr=head_ptr;
source_ptr=source_ptr->link;
while(source_ptr!=NULL)
{
temp = new nodeType;
temp->link=NULL;
temp->info =source_ptr-> info;
tail_ptr->link=temp;
tail_ptr = tail_ptr->link;
source_ptr = source_ptr->link;
}
}
Header file
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdlib>
using namespace std;
class Bubble
{
private:
int manynodes;
public:
Bubble() { }
void Bubblesort();
friend ostream &operator<<( ostream &output, const Bubble &D )
{
output << D.manynodes;
return output;
}
friend istream &operator>>( istream &input, Bubble &D )
{
input >> D.manynodes;
return input;
}
};
Your extraction operator looks fine. I don't know if it really does what you need, but that's another issue.
You are declaring function Bubblesort() twice: first in the header file as void Bubblesort(), then in the main file as just Bubblesort() (this should at least give you a warning that it is considered to mean int Bubblesort()). You cannot overload a function just on the return value, hence the error.
Indeed, you are using a type called node in several places, but you have not declared nor defined it anywhere.