Hello this is the code:
template <class T> class FibonacciHeap{
public:
class Entry{
public:
// Returns the element represented by this heap entry.
T getValue(){
return mElem;
}
// Sets the element associated with this heap entry.
void setValue(T value){
mElem = value;
}
// Returns the priority of this element.
double getPriority(){
return mPriority;
}
private:
int mDegree = 0; // Number of children
bool mIsMarked = false; // Whether the node is marked
Entry mNext; // Next element in the list
Entry mPrev; // Previous element in the list
Entry mChild; // Child node, if any
Entry mParent; // Parent node, if any
T mElem; // Element being stored here
double mPriority; // Its priority
//Constructs a new Entry that holds the given element with the indicated priority.
Entry(T elem, double priority){
mNext = mPrev = this;
mElem = elem;
mPriority = priority;
}
};
...
In the Class "Entry" I want to call Entry recursively, so I can use:
First_entry.mPrev.mNext
I know this works in Java, but when I compile this in c++, I get:
error: 'FibonacciHeap<T>::Entry::mNext' has incomplete type
Does anyone know how to fix this or work around this?
Based on the variable names and initializers here, I'm assuming you're adapting my Java Fibonacci heap into C++. :-) If so, best of luck!
In Java, if you have a variable of type Entry, it acts like a C++ variable of type Entry* in that it's a pointer to another Entry object rather than an honest-to-goodness Entry object. As a result, in the definition of the Entry class, you should adjust the fields so that they're of type Entry* rather than Entry. Similarly, instead of using the . operator to select fields, you'll want to use the -> operator. So
First_entry.mPrev.mNext
would be rewritten as
First_entry->mPrev->mNext
Don't forget to explicitly initialize the Entry pointers to nullptr - Java does this automatically, which is why there are no initializers in the Java version. However, C++ gives uninitialized pointers garbage values, so make sure to give mChild and mParent an explicit nullptr value.
Related
I'm trying to create a linked list that has 2 data types and a function that inserts nodes. But in order to insert nodes, I have to create at least 1 empty node first.
linked list struct
struct receipt{
string name;
double price;
receipt* link;
};
function that inserts a node at the end of the list
void insert(receipt** head_name_ref, string new_name, double new_price)
{
receipt* new_name_node = new receipt();
receipt *last = *head_name_ref;
new_name_node->name = new_name;
new_name_node->price = new_price;
new_name_node->link = NULL;
if (*head_name_ref == NULL)
{
*head_name_ref = new_name_node;
return;
}
while (last->link != NULL)
{
last = last->link;
}
last->link = new_name_node;
return;
}
function that print the list
void printList(receipt* n){
while(n!=NULL){
cout<<"Name: "<<n->name<<'\t'<<" ";
cout<<"Price: "<<n->price<<'\t'<<" ";
cout<<endl;
n=n->link;
}
}
main function
int main(){
receipt* head = NULL;
head = new receipt;
insert(&head, "item", 23);
printList(head);
return 0;
}
here is a picture of the output https://i.stack.imgur.com/6Ss02.png
Consider that in a more complex program you would have much more than simply a main function. When creating a data structure you have to store a pointer or reference to an object in some way that other functions can receive or access the pointer. For something this simple a global variable or instance of a struct containing the attributes of the list would suffice. Simply initialize the head to 0 and create the functions needed to manage that global object. Upon the first instantiation of the node, simply assign the head to that pointer.
You've already created a struct that represents a node. Now create another one that represents the list which contains nodes. Within that struct you'd want attributes such as a head that pointers to the first node object or null if it is empty. You can give it a default constructor.
Since this looks like an assignment I'm only giving you some hints and not a complete example, purposefully.
struct SinglyLinkList {
receipt* head;
SinglyLinkList() : head(0) {}
~SinglyLinkList() { // code to iterate and destroy all node objects }
// now define copy constructor and assignment operators if you want or delete those
// possibly some methods to add, remove, print nodes
void print();
add(receipt* r); // could overload to insert at a position
remove(size_t n); // remove nth receipt or overload to remove by some other factor
void removeAll();
receipt
};
// somewhere above the main function you could just instantiate a global list
// Within the main function you may call methods that operate on the
// list and call its methods, or define other global functions if you
// prefer that the list be defined only with the attributes
SinglyLinkList list; // default constructed with head = 0 or head = nullptr if you prefer
First note that when struct receipt is constructed, price and link will be uninitialized (std::string name will be default constructed to an empty string, but double and pointers do not have such a default initialization). This problem will manifest with this line in main:
head = new receipt;
(the problem does not manifest when you create new_name_node because you manually initialized it after the allocation).
Therefore you should better handle struct receipt initialization. The minimum would be something like this:
struct receipt {
std::string name;
double price{ 0 };
receipt* link{ nullptr };
};
You can consider to add a custom constructor.
Now to answer you question:
The question title is how to avoid printing the first node.
To do this you just have to skip one node before starting the loop.
Add the following at the beginning of printList:
if (n != nullptr)
{
n = n->link;
}
However, "solving" the problem like this is not a good idea.
Having a "dummy" first node in a linked list is not the ideal design.
I suggest you redesign your code to avoid it. You can search the web for typical linked list implementations to get some ideas. Then the issue of printing (while skipping a node) will not arise at all.
On a side note: better to avoid using namespace std - see here Why is "using namespace std;" considered bad practice?.
I have to implement a two way ordered list at a specific way, and I got stuck. I have a Bag class that has an Element class inside it. Now the problem is when I want to place an item inside the bag.
An element has a key (its value), a pointer to the smaller element (_down), and one to the larger (_up). When I put a new element inside the bag the code is the following (names translated so it's easier to understand)
void Bag::put(int e) {
if(_item_count==0){
Element *element = new Element(e, nullptr, nullptr);
_bot = element;
_top = element;
}else{
Element *p = _bot;
while(e > p->key()){
p = p->up();
}
Element *element = new Element(e, p, p->down());
p->down() = element;
}
}
So the problem is that p->down() is not assignable. I guess I should return the pointer by reference, but I don't know how to do that.
down() function
Bag::Element *Bag::Element::down() {
return _down;
}
I tried putting & at great many places, but I just can't figure out how to make it all work.
Here's the full code if needed, but it's variables are mostly Hungarian, I'll provide translation if needed.
Header on the left, cpp on the right
This will return a non-const lvalue reference to pointer which is good to be assigned to:
Bag::Element *&Bag::Element::down() {
return _down;
}
And perhaps you should also provide a const overload:
Bag::Element * const &Bag::Element::down() const {
return _down;
}
Of course you should update your class declaration accordingly.
And also you may consider using a struct for such simple classes like Element while making pointer fields public (which is the default access control for structs. Typically you won't get bashed for doing this in C/C++, unlike in Java where people tend to insist on using private fields and getter/setters even for super simple classes. (I'm not saying this good or bad, just a sort of convention.)
Just assign the pointer directly:
p->_down = element;
Note that you are only modifying the "down" pointer of the next element. You also need to modify the "up" pointer of the previous element.
Note also that your new element may be the first or the last element in the list, you should handle these cases specially. Once you do that, you may discover that special handling of the empty list is unnecessary.
I am studying C++ from Herbert Schildt's book "Teach Yourself C++ 3rd Edition". In one example code, something made me so confused.
#include <iostream>
using namesapce std;
template <class data_t> class list {
data_t data;
list *next;
public:
list(data_t d);
void add(list *node) {node->next = this; next = 0; }
list *getnext() { return next;}
data_t getdata() { return data;}
};
I didn't write all code in example, I only writed class declaration.
In here, I didn't understand one part. First, the "*node" pointer which belongs to "add" function, is using as "node->next" for "*next" pointer. I didn't understand the aim in here, why we don't directly use like {"next=this; next=0;} ? Also, how can we use an empty pointer (*node) to point another empty pointer (*next) ? I am missing maybe some key concepts, thanks for helps.
In the function add():
template<typename data_t>
class list {
// ...
void add(list *node) {node->next = this; next = 0; }
// ...
};
The point of the function is to add this to the list, as the next element after node. Think about it like a train: add() tells the current car to hook itself onto the back of another car, with the function's parameter telling it which car to link to.
Note that this function expects node to not be a null pointer; if it is null, you'll probably get a segmentation fault.
void add(list* node) {
node->next = this; // Tells "node" to register the current node as its "next" node.
// Should first check whether "node" is a valid pointer.
next = 0; // Tells the current node to register a null pointer as its "next" node,
// signifying that it's currently the last node in the list.
// Note that instead of assigning 0, it should instead assign either
// "nullptr" (C++11 or later) or "NULL" (pre-C++11).
}
Therefore, when used like this:
list<int> start(42), second(24);
second.add(&start);
It will do the following:
(&start)->next = &second;
(&second)->next = 0;
This creates a singly linked list, which looks like this:
Start: "start"
--> Next: "second"
--> Next: None.
Or, more concisely:
start->second->NULL
Remember, when inside a non-static member function, any member variable accesses are assumed to operate on this unless otherwise specified.
template<typename data_t>
void list<data_t>::add(list* node) {
node->next = this; // Operates on node, not on this.
next = 0; // Operates on this; becomes "this->next = 0;"
}
If this function intstead was just {next = this; next = 0;}, then it would be:
template<typename data_t>
void list<data_t>::add(list *node) {
this->next = this; // Bad. Creates a circular linked list, where "this" is ALWAYS the
// next node after "this".
this->next = 0; // Renders the above line entirely pointless, by indicating that there
// are no nodes after "this".
}
I'm implementing a recursive data structure in c++ using classes. I'm having some trouble implementing it particularly with the "this" pointer.
In one function, I need to modify the "this" pointer. However that is not allowed. How do I do it? I read somewhere that you will need to pass "this" pointer to that function to change it. However I'm not clear with that. Does that behave like python's "self"? An example would be great
EDIT:
void insert(int key)
{
if (head == NULL)
{
/* I need to insert in beginning of structure */
List* tmp;
tmp->key = key;
tmp->next = this;
this = tmp; /* This does not work */
}
}
Thank You!
You cannot modify the this pointer, given that it behaves as if declared T* const. What you could do is hold a pointer to your own type inside of the class, and modify that.
class foo
{
/* ... */
private:
foo* p; // this can be modified
};
You cannot modify this, period. You need to re-structure your program so that you don't need to do that.
The best way to insert the way you're trying to is to create a double linked list, not a single one (with only the next pointer). In other words, you should have a previous pointer that points to the previous node in the list to properly insert using the this pointer. Else you need to insert from the parent node of the this.
ie with a double linked list:
Node* tmp = new Node;
tmp->key = key;
this->previous->next = tmp;
tmp->previous = this->previous;
tmp->next = this;
this->previous = tmp;
Edit:
Don't forget that "this" is ""simply"" a memory address so what you want to change is what's contained in it.
I have this code that in my mind, it recieved an item called Vehicle and it has to store it in an array called Node. This is the code related to this part of the program:
void Table::process(Vehicle v, int cont) {
char a='A'+cont;
putVehicle(a,v);
Node.a_v[cont]=v;
if(cont==0) a_surt=v.rowVehicle();
}
This is how I have the array on the private part of Table.h:
struct Node{
Vehicle a_v;
};
The error I get is:
error: expected primary-expression before '.' token
I have the includes I need, but everytime I type this: Node.a_v It gives me that error.
Any advice?
If you want to use a struct, you need to declare a Node before using it. Also, the struct needs to contain an array (or better, look into vectors for more flexibility).
struct Node {
Vehicle[10] a_v; // 10 is max number of Vehicles in array
};
Node myNode;
myNode.a_v[cont] = v;
Remember that if you want to keep this Node around and put more things in it, it needs to be declared in the right scope. For example, to have your process function add a Vehicle to a Node that exists outside of the function process, you could something like this:
void Table::process(Node n, Vehicle v, int cont) {
char a = 'A'+cont;
putVehicle(a,v);
if (cont < 10) {
n.a_v[cont] = v;
}
if (cont == 0) a_surt = v.rowVehicle();
}
It kind of looks like you're just trying to use an array. In that case you're looking for something like this:
// This would go somewhere in your program. Again, 10 is just an example.
Vehicle vehicleArray[10];
// Send this array to this function
void Table::process(Vehicle[] vArray, Vehicle v, int cont) {
char a = 'A'+cont;
putVehicle(a,v);
if (cont < 10) { // In a real program, don't hard-code array limits.
vArray[cont] = v;
}
if (cont == 0) a_surt = v.rowVehicle();
}
You should use Node object to get access to the a_v variable. This line
Node.a_v[cont]=v;
Is incorrect. You should do something like that:
Node n;
n.a_v[cont]=v;
everytime I type this: Node.a_v It gives me that error.
Node is a type; types define the structure of a objects, but they do not have fields of their own (except the static fields, which belong to all instances at once; they are accessed differently anyway).
In order to use a . or -> operator, you need an instance of a Node, like this:
Node x;
x.a_v = ...
It is not clear in your case from where the Node instances should be coming, though. In order to access them, you would need to either pass them in as parameters, or make them available statically/globally (not recommended).
Okay, so Node is NOT the name of your array. It's the name of a user-defined type that is supposed to contain an array. Your Node, however, does not contain an array. It contains one Vehicle, named a_v. I assume a_v is supposed to represent an Array of Vehicles. Therefore, you need to allocate the array. Something like this:
struct Node {
Vehicle a_v[AMOUNT];
};
If you don't know at compile-time how large you want your arrays to be, then they must be dynamically allocated, like this:
struct Node {
Vehicle* a_v;
Node() {
a_v = new Vehicle[AMOUNT];
}
};
If it's dynamically allocated, then it must also be deallocated:
struct Node {
Vehicle* a_v;
Node() {
a_v = new Vehicle[AMOUNT];
}
~Node() {
delete[] a_v;
}
};
AND if it's dynamically allocated, you need to add provisions for copying or disable copying:
struct Node {
Vehicle* a_v;
Node() {
a_v = new Vehicle[AMOUNT];
}
~Node() {
delete[] a_v;
}
// Disable copies (with C++11 support):
Node(const Node&) = delete;
Node& operator=(const Node&) = delete;
// Disable copies (without C++11 support) by making them private and not defining them.
private:
Node(const Node&);
Node& operator=(const Node&);
};
Then to access one of the Vehicles, you'd need to do so like this:
Node n; // Declare a node, which contains an array of Vehicles
n.a_v[cont] = v; // Copy a Vehicle into the array of Vehicles
Note, however, that if you declare the Node instance in this function, then it is local and it will go out of scope as soon as your function ends. You need to declare the Node instance as a member of your Table if you want it to persist past the function call.
class Table
{
private:
Node n;
};
Lastly, as others have suggested, I'd highly recommend that you read a C++ book to learn C++. My personal recommendation is this book (5th edition, don't buy 6th or 7th - the author of those editions is terrible).