void add_at_end(string node_data, sll_node *front, sll_node *end)
{
//NB: it's these little things that I screw up on
// like if asked quickly do we include asterisk in declaring a new node
// it's yes BUT do you know why????
sll_node *newNode = new sll_node;
newNode->data = node_data;
newNode->next = NULL;
//If list is empty, then head and tail pts to the newNode
if ( front == NULL && end == NULL )
{
front = newNode;
end = newNode;
}
//Else the list is not empty, so just update tail ptr and leave head ptr alone!
else
{
end->next = newNode;
end = newNode;
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13
int main()
{
sll_node *front = new sll_node;
sll_node *end = new sll_node;
front = NULL;
end = NULL;
add_at_end("A", front, end);
add_at_end("AA", front, end);
add_at_end("DDEE", front, end);
return 0;
}
You need to pass in the front and end pointers by reference; that is, you need to pass in the address of the pointer. They're being treated as local variables within the function as it stands.
I have updated add_at_end to take the address of the head/end and updated the calls to add_at_end. I also added a print function to print the list after each add.
#include <iostream>
#include <string>
usingnamespace std;
struct sll_node
{
string data;
sll_node *next;
};
void add_at_end(string node_data, sll_node **front, sll_node **end)
{
//NB: it's these little things that I screw up on
// like if asked quickly do we include asterisk in declaring a new node
// it's yes BUT do you know why????
sll_node *newNode = new sll_node;
newNode->data = node_data;
newNode->next = NULL;
//If list is empty, then head and tail pts to the newNode
if (*front == NULL && *end == NULL)
{
*front = newNode;
*end = newNode;
}
//Else the list is not empty, so just update tail ptr and leave head ptr alone!
else
{
(*end)->next = newNode;
*end = newNode;
}
}
ostream& print(ostream& os, sll_node* p)
{
while (p)
{
os << p->data << '\n';
p = p->next;
}
os << '\n';
return os;
}
int main()
{
sll_node *front = 0;
sll_node *end = 0;
add_at_end("A", &front, &end);
print(cout, front);
add_at_end("AA", &front, &end);
print(cout, front);
add_at_end("DDEE", &front, &end);
print(cout, front);
return 0;
}
so when we pass by reference (the ** in the add_to_end function), is it b/c we don't know what mem address user will user for the node pointers, i don't even know what i'm saying.
Each node, the head and the end values are of type sll_node*.
You have an append function called add_at_end which takes the head, end and payload data. This function is correct, except it doesn't update head and end. It doesn't do so because they are passed by value.
because I thought front is a pointer so we want it to store memory address of newNode...i'm confused now b/c isn't *front = newNode the dereference operator...
I don't know why this is so complicated for me, there's pass by value, pass by reference and pass by address...i'm going to have to look up myself, appreciate all your help and patience thanks
It is tricky, it all comes form C and that is necessarily a primitive language.
C has no pass by reference, it only has pass by value.
Internally, languages that pass by reference pass the address of the variable. It's just syntactic sugar to not dereference the parameter in the function.
Although C has no pass by reference, it does achieve the same effect by allowing you to pass the address of a variable. The catch is that in the function, you need to explicitly dereference the variable before you use it.
The example I gave uses this method to pass in the pointer. However, as C++ provides pass by reference, you can do the same thing using references. I tend to use typedefs to simplify type declarations. Here's the original post with references.
#include <iostream>
#include <string>
usingnamespace std;
struct sll_node
{
string data;
sll_node *next;
};
typedef sll_node* psll_node;void add_at_end(string node_data, psll_node &front, psll_node &end)
{
//NB: it's these little things that I screw up on
// like if asked quickly do we include asterisk in declaring a new node
// it's yes BUT do you know why????
sll_node *newNode = new sll_node;
newNode->data = node_data;
newNode->next = NULL;
//If list is empty, then head and tail pts to the newNode
if (front == NULL && end == NULL)
{
front = newNode;
end = newNode;
}
//Else the list is not empty, so just update tail ptr and leave head ptr alone!
else
{
end->next = newNode;
end = newNode;
}
}
ostream& print(ostream& os, sll_node* p)
{
while (p)
{
os << p->data << '\n';
p = p->next;
}
os << '\n';
return os;
}
int main()
{
sll_node *front = 0;
sll_node *end = 0;
add_at_end("A", front, end);
print(cout, front);
add_at_end("AA", front, end);
print(cout, front);
add_at_end("DDEE", front, end);
print(cout, front);
return 0;
}
just curious, when we want to add a new node, we create a new node structure and then make tail pointer point to it, but shouldn't we also delete the pointer to which tail pointer points to now since it's unnecessary, I mean:
In all fairness, rather than dealing with pass-by-references issues, you should have wrapped it all into a List class and made "add_at_end" a member function.
i hope i make sense, i mean that since when we set: tail = newNode, we are making tail pointer point to address allocated by the newNode, so can't we just delete newNode since it's address is stored by tail? I think i'm thinking overboard with this pointers stuff...