#include <cstdlib>
#include <iostream>
#include "Node.h"
#ifndef HW4_H
#define HW4_H
using namespace std;
/**
You are to implement the two functions in this class.
You can add any other method or members to it as well.
However, you cannot change their signature.
**/
class HW4{
public:
int count(Node* r) const
{
if(r->next==NULL&&r->bro==NULL) { return 0;}
if(r.isLeaf())
{
return ((1+count(r->next)+count(r->bro)));
}
count(r->next);
}
/*
This method will return true if the tree rooted at node sn can answer
the demand induced by its leaves.
*/
bool canDemandBeAnswered(Node* root)
{
if(count(root)>(root.getCapacity()))
{
return 0;
exit(0);
}
else
{
return (canDemandBeAnswered(root->next)&&canDemandBeAnswered(root->bro));
}
}
/*
This method should return a linked list of nodes representing the
customers with the overall highest revenue.
The resulting list should conform to the capacity limitations.
*/
// Node* getBestCustomers(Node* root);
};
#endif
#include <cstdlib>
#ifndef NODE_H
#define NODE_H
/**
The Node class. You must implement the two methods isLeaf() and addChild(Node*) below.
Otherwise, you can add any methods or members your heart's desire.
The only limitation is that they have to be in this file.
**/
class Node {
private:
int capacity;
int price;
public:
/**
Hint: to be used for saving the Node's children and for returning the linked list
**/
Node* next;
Node* bro;
Node(){
capacity = 0;
price = 0;
}
Node(int capacity_){
capacity = capacity_;
price = 0;
}
//should return true if this node has no children, false otherwise.
//this method adds a child to this node.
int getCapacity(){
return capacity;
}
int getPrice(){
return price;
}
void setPrice(int price_){
price = price_;
}
bool isLeaf()
{
if((this->next)->capacity==0)
return 1;
else return 0;
}
void addChild(Node* child)
{
Node* temp;
if(this->next!=NULL)
{
temp=this->next;
child->bro=temp;
this->next=child;
}
else
this->next=child;
}
};
#endif
I get the following error: "isLeaf() has not been declared". I don't understand why - I declared both.
bool canDemandBeAnswered(Node* root)
{
if(count(root)>(root.getCapacity()))
This attempts to call getCapacity on a Node *. But Node * doesn't have a function called getCapacity -- Node does.
You can use (*root).getCapacity() or the shorthand, root->getCapacity().
if(r.isLeaf())
You have the same issue here. r is a Node *.
Did you mean r->isLeaf() instead of r.isLeaf(), since r is a pointer?
You should be using -> instead of . to access those functions because r is a pointer.
Member access for pointers is different. You must use the indirection operator ->. These are not the actual objects but just pointers to them.
Related
I stumbled across this question in an old textbook I bought ages ago, whilst strictly speaking it is not too difficult, I could not find a post here that simply answered this one question. As such I thought "Hey perhaps someone starting out might be confused about this", and so I put together the following code:
#include <iostream>
using namespace std;
// Structures
struct charNode {
char Node;
charNode *next;
};
// Functions
charNode* getCharNode(char c) {
return ; //<----- Return Node Here
}
What this needs is to be put in a class or else you must have a global variable that points to the head of that singly linked list.
An example class could look like this:
#include <iostream>
class singly_linked_list {
struct charNode {
char Node;
charNode *next;
};
public:
// find the charNode with the value `c`:
charNode* getCharNode(char c) {
for(charNode* curr = head; curr != nullptr; curr = curr->next) {
if(curr->Node == c) return curr;
}
return nullptr;
}
// add member functions to add/remove charNode's from the list etc
// and implement one of "the rule of 3" or "the rule of 5"
private:
charNode* head = nullptr;
};
You can implement getCharNode() function like in following code. I used this function for an example of creating singly linked list of chars. Also created extra function print_list() which outputs linked list to console.
Notice that I did only allocation of nodes (new operator), and didn't do deallocation (delete), I left this task for you to do, if you care about memory leaks.
Try it online!
#include <iostream>
// Structures
struct charNode {
charNode(char value, charNode * _next = nullptr)
: Node(value), next(_next) {}
char Node;
charNode *next;
};
// Functions
charNode* getCharNode(char c, charNode * next = nullptr) {
return new charNode(c, next);
}
void print_list(charNode const * node) {
if (!node)
return;
std::cout << node->Node << " ";
print_list(node->next);
}
int main() {
charNode * list = getCharNode('a',
getCharNode('b', getCharNode('c')));
print_list(list);
}
Output:
a b c
I'm trying to insert a Packet object into this binary search tree. But the problem is, I don't really know of a good-enough way of doing this or how to go about doing it. I'm looking for some pointers in the right direction and to be shown what to do to tackle this problem.
Please:
Ignore my usage of namespace std; because this is for educational
purposes and I'm not rly (as of now) looking to go further than that!
Help me with my specific question and if possible, show me how I
could fix this problem.
<< Take a look at my code >>
Main.cpp:
#include <iostream>
#include "BST.h"
#include "Packet.h"
// IGNORE the USAGE of namespace std. as this is purely a testing program for educational purposes.
// It is NOT implementation for a real program.
using namespace std;
int main() {
cout << "-------------------------------------------------------" << endl;
cout << "Testing BST" << endl;
cout << "-------------------------------------------------------" << endl;
BST test1;
Packet packetTest(123, "This is a packet of cheese.", 12.95, 10);
// test1.insert(How should I choose to insert Packet? That's the question.);
system("pause");
}
BST.h:
#pragma once
#include "Packet.h"
using namespace std;
class BST {
struct Node {
Node() : rlink(nullptr), llink(nullptr) {};
~Node() {};
// Store packet here (for instance Packet *data or something)...
Node *rlink, *llink;
};
public:
BST();
// void insert(How should I choose to insert Packet? That's the question.);
void insert(Node *&p, Node *newNode);
void preorderTraversal() const;
void destroyTree();
~BST();
private:
Node * root;
void destroyTree(Node *&p);
void preorderTraversal(const Node *p) const;
};
BST.cpp (need guidance here, see below code to see what I mean):
#include "BST.h"
#include <iostream>
BST::BST() : root(nullptr) {}
// Need guidance here. What should I do for this function? How can I insert this object called Packet into the BST?
/*void BST::insert(How should I choose to insert Packet? That's the question.) {
Node *newNode = new Node;
...
insert(root, newNode);
}*/
void BST::insert(Node *&p, Node *newNode) {
if (p == nullptr) {
p = newNode;
}/*else if (p's data's getPartId() > newNode's data's getPartId()){
insert(p->llink, newNode);
}*/else {
insert(p->rlink, newNode);
}
}
void BST::preorderTraversal() const {
if (root == nullptr) {
cerr << "There is no tree.";
}
else {
preorderTraversal(root);
}
}
void BST::preorderTraversal(const Node *p) const {
if (p != nullptr) {
// cout << p->data->getPartId() << " "; Need to handle Packet's data here. But we need to implement Packet insection first!
preorderTraversal(p->llink);
preorderTraversal(p->rlink);
}
}
void BST::destroyTree(Node *&p) {
if (p != nullptr) {
destroyTree(p->llink);
destroyTree(p->rlink);
delete p;
p = nullptr;
}
}
void BST::destroyTree() {
destroyTree(root);
}
BST::~BST() {
destroyTree(root);
}
Packet.h:
#pragma once
#include <string>
using namespace std;
class Packet {
public:
Packet(int partId, string description, double price, int partCount) :
partId(partId), description(description), price(price), partCount(partCount) {}
int getPartId() const { return partId; }
private:
int partId;
string description;
double price;
int partCount;
};
This was my previous implementation of insert in BST.cpp:
void BST::insert(Packet &data) {
Node *newNode = new Node;
newNode->data = &data;
insert(root, newNode);
}
As you can see, I don't believe that this is ideal. I mean I had to use & reference twice. Is there a more elegant solution and may I get guidance in regards to that?
Q: How can I insert this object called Packet into the BST?
A: To create a relationship between the BST and Packet class, you must define one in some sort of way. Best practice calls for an association which imposes the least amount of coupling between the related classes.
I have implemented an association in your solution in the place I found most suitable ie. the rlink and llink pointers of struct Node of class BST.
// Store packet here (for instance Packet *data or something)...
Packet* rlink, * llink;
A relationship is the only way you will be able to access getPartId() from a Node or BST object. Albeit the Packet class does not manage any resources so it does not require memory management, association is just a fancy word for a loosely coupled relationship between classes, which is the case here.
Be careful when calling functions recursively, as you have in void BST::insert(Node *&p, Node *newNode). You shouldn't call a function recursively without an exit condition and never really use recursion unless you have to as iterations are a stack-memory saving alternative. I saw no need for recursion in your insert function so I took it out. I'm hoping what I replaced them with is of some use to you:
void BST::insert(Packet& p) {
Packet* newPacket = new Packet(p);
insert(root, newPacket);
}
void BST::insert(Node*& p, Packet* newPacket) {
if (p == nullptr) {
p = new Node;
p->llink = newPacket;
}else if ((p->llink->getPartId()) > newPacket->getPartId()){
p->llink = newPacket;
}else {
p->rlink = newPacket;
}
}
I then went on to say:
void BST::preorderTraversal(const Node* p) const {
if (p != nullptr) {
cout << p->llink->getPartId() << " \n";
}
}
void BST::destroyTree(Node*& p) {
if (p != nullptr) {
delete p;
p = nullptr;
}
}
As I said, a relationship is the only way you will be able to access getPartId() from a Node or BST object.
Regarding the comments, I agree. Encapsulation requires keeping all data members private and only exposing methods when you have to. My solution allows you to keep the function
private:void insert(Node*& p, Packet* newPacket);
As you have kept Node completely hidden by overloading the preorderTraversal()
Good job and hope I helped!
I want to implement single linked list with a header class but i am also trying making information and pointer of linked list private and compiler says me
lvalue required as left operand of assignment
pred->Next()=temp->Next();
What's the wrong with this code?
#include <iostream>
using namespace std;
class IntSLLNode{
private:
int info;
IntSLLNode * next;
public:
IntSLLNode(){
next=0;
}
IntSLLNode(int el,IntSLLNode *ptr=0){
info=el;
next=ptr;
}
int Info(){return info;}
IntSLLNode * Next(){return next;}
};
IntSLLNode * head,* tail;//header structure
class IntSLList{
IntSLList(){
head=0; tail=0;
}
public:
void addToHead(const int&);
void addToTail(const int &);
int deleteFromHead();
int deleteFromTail();
void deleteNode(int&);
void listele();
};
void IntSLList::addToHead(const int &el){
head=new IntSLLNode(el,head);
if(tail==0)
tail=head;
}
void IntSLList::addToTail(const int &el){
if(tail==0){
head=tail=new IntSLLNode(el,head);
}
else{
tail->Next()=new IntSLLNode(el);
tail=tail->Next();
}
}
int IntSLList::deleteFromHead(){
if(head==0){
cout<<"No value such that";
return -1;
}
int el=head->Info();
IntSLLNode * temp=head;
if(head==tail){
head=tail=0;
}
else{
head=head->Next();
}
delete temp;
return el;
}
First of all, you need to understand the difference between lvalue and rvalue. In simple words, lvalue is something that can be assigned (variable etc.) while rvalue is a temporary value (just like the one that you are returning here: IntSLLNode * Next(){return next;})
Then, by trying to assign something to rvalue, you get an error.
As a solution here, you could make your IntSLLNode * next; public or return a reference to this class member in your Next() function.
Assignment to a return value of a function/method would not do anything useful. You can only assign to a reference of a value returned by a function.
class IntSLLNode{
...
int& Info(){return info;}
IntSLLNode*& Next(){return next;}
};
But then, it would break encapsulation of that node and would allow any external code to change the linking of your nodes in the list by mistake. Personally I would hide the whole node class into the list class and provide methods to access Info() values to code outside this file.
I am currently using VS2015 for this.
I am trying to create a binary search tree in c++ so that I can learn both the language and the data structure while trying to see if I can follow good practices. However, I am coming through a problem where I am not properly instantiating the object properly in the driver file.
BSTHeader.h
#pragma once
/*
Properties of Binary Search Tree:
1.) Elements less than root will go to the left child of root
2.) Elements greater than root will go to the right child of root
*/
#include <memory>
// Binary Search Tree handler class
class BSTHeader {
/*
Naive implementation of BSTNode (non-generic version)
Nested class is private, but it's internal fields and member functions
are public to outer class: BSTHeader
*/
class BSTNode {
public:
int data;
std::unique_ptr<BSTNode> left;
std::unique_ptr<BSTNode> right;
BSTNode(int val) {
data = val;
left = NULL;
right = NULL;
}
~BSTNode() {}
};
std::unique_ptr<BSTNode> root; // Root of BST
unsigned int size; // Total amount of nodes in tree from root
public:
BSTHeader();
BSTHeader(int val);
~BSTHeader();
bool insert(std::unique_ptr<BSTNode>& root, int val);
}
BSTHeader.cpp
#include "BSTHeader.h"
/*
Constructors:
*/
BSTHeader::BSTHeader() {
root = NULL;
size = 0;
}
BSTHeader::BSTHeader(int val) {
root = std::unique_ptr<BSTNode>(new BSTHeader::BSTNode(val)); // Smart pointer to an internal BSTNode
size = 1;
}
BSTHeader::~BSTHeader() {} // Empty destructor from use of smart pointer
/*
Member functions:
*/
bool BSTHeader::insert(std::unique_ptr<BSTNode>& root, int val) {
if (root == NULL) { // Place new element here
root = std::unique_ptr<BSTNode>(new BSTHeader::BSTNode(val));
size++;
return true;
}
if (val < root.get()->data) { // val < root
insert(root.get()->left, val);
}
else if (val > root.get()->data) { // val > root
insert(root.get()->right, val);
}
The issue I get is here, where I believe I am trying to instantiate a BSTHeader object.
Program.cpp
#include "BSTHeader.h"
int main()
{
BSTHeader::BSTHeader bst(); // <----- ERROR
return 0;
}
The error I am getting is cannot determine which instance of overloaded function "BSTHeader:BSTHeader" is intended
However, whenever I do:
BSTHeader bst()
I am not able to access the insert(..., ...) function for the object doing bst.insert(..., ...) due to expression must have class type even though the error above does not appear.
Yet everything works fine and I am able to access all the member methods by doing this: BSTHeader bst(5) by using the overloaded constructor.
I am not sure whether its a namespace issue or not. I feel as though I am missing something.
The line
BSTHeader::BSTHeader bst(); // <----- ERROR
is a declaration of a function named bst that takes no arguments and returns a BSTHeader::BSTHeader.
This is known as the "most vexing parse", and often described in less polite language.
If you want to instantiate an instance, giving the constructor no arguments, remove the ().
I need help finding and returning a "node" in a general tree structure. Each node can have more than 2 children so it's not a binary tree. I've been given the following code, this Element object has a list to contain its children, I create one element node pointer in main and using that I have to add and search for children. This is for a school project but I'm not looking for answers (an answer wouldn't hurt). Any advice on how to go about this problem would be much appreciated, thanks!
#pragma once
#include <iostream>
#include <list>
#include <sstream>
using namespace std;
class Element
{
private:
list<Element*> children;
char* _tag;
int _value;
// private methods
public:
// default constructor
Element();
// non-default constructors
Element( char* name); // value is set to -99 if not given
Element(char* name, char* value);
// destructor, must recursively destruct its children
// and release the memory allocated for _tag
~Element();
// ostream operator ( pre-order traversal)
friend ostream& operator << (ostream& out, const Element& E);
void display_xml(); // print out the tree in xml-- format
void addChild( Element* child); // add a child
// Find the first element such that _tag == tag
// returns “this” pointer of this element
Element* findTag( char* tag);
char* getName();
int getValue();
void setName(char* name);
void setValue( int value);
int height(); //b return the height
int size(); // return the size
// other methods
};
this is my best attempt at a solution, it has obvious problems but I'm new to all of this and some explanation on a proper solution, or some sample code would be very helpful!
Element* Element::findTag(char* tag)
{
list<Element*> temp = children;
int s = temp.size();
if(getName() == tag)
{
return this;
}
else
{
for(int i = 0; i < s; i++)
{
findTag((*temp.front()).getName());
temp.pop_front();
}
}
}
I will give you a pseudo-code for searching for a node that has a value val in a tree rooted at root:
find(Node root, val)
if(root.value == val) return root //-- if the recursion found the node we are searching for
else
for every child x of root //-- re-cursing on the children of root
if(find(x, val) != null) return x //-- if one of the calls found the node we are searching for
return null //-- if we did not find the node we want in the sub-tree rooted at root