Let's make a list
struct node
{
node *next=nullptr;
int value=0;
};
Why do we start a list with a pointer node *head=nullptr, but not with an object node head? Is such an implementation faster than creating each node as an object whose fields are a value and a pointer to the next object? I don't understand how this implementation works.
I added function that adds new node to the front
void addFront(node *&head, int value)
{
node *nodeToAdd=new node;
nodeToAdd->value=value;
nodeToAdd->next=head;
head=nodeToAdd;
}
and another one that shows the list.
addFront(head1, 2);
showList(head1);
node *head2=new node;
addFront(head2, 2);
showList(head2);
Why first showList display 2 and the second one 2 0? The only difference is in head1 and head2 declaration.
Related
The Definition of the structure is as follows.
//Structure of the linked list node is as follows:
struct Node {
int data;
struct Node* next;
Node(int x) {
data = x;
next = NULL;
}
};
I have to complete this function which I have completed this way. I am trying to create a Node using the newData parameter passed in the function definition. But it shows the error which I have attached below.
// function inserts the data in front of the list
Node* insertAtBegining(Node *head, int newData) {
//Your code here
struct Node* newNode(newData);
struct Node* temp;
temp=head;
head=newNode;
newNode->next=temp;
}
I get this error while I am create a node by passing newData as parameter to struct Node *newNode(newData);
In function Node* insertAtBegining(Node*, int):
prog.cpp:67:32: error: invalid conversion from int to Node* [-fpermissive]
struct Node *newNode(newData);
Thank You for your help.
Your constructor returns a Node, not a Node*, so when you try to initialize newNode, the compiler thinks you're trying to create a pointer using an int. Instead you should be expecting your constructor to give you a Node:
Node newNode(newData);
Your insertAtBegining() implementation needs to create a new Node object. You aren't doing that. Right after your teacher's Your code here comment, your attempt has defined a "Node pointer" variable (whose type is Node*), but your attempt hasn't initialized that to any Node object (data that would have been passed to an object's constructor isn't the same as the object itself).
Also, you don't need to keep repeating struct that way that us old guys used to do with old-fashioned C code.
Lastly, you seem to also want to return the list's new head node back to the function's caller, but are unclear how you want to achieve that. There are two ways. The way that your code seems to be leaning towards is returning the new head in the same head parameter. In that case, it should look like this:
void insertAtBegining(Node** head, int newData)
{
//Your code here
Node* newNode = new Node(newData);
Node* temp;
temp = *head;
*head = newNode;
newNode->next = temp;
}
(The head parameter could also have been a "reference to a Node*", instead of this "pointer to a Node*", by making appropriate changes to the code.)
The second option (which maintains your teacher's recommended function signature) is to return the new head via the function's return value:
Node* insertAtBegining(Node* head, int newData)
{
//Your code here
Node* newNode = new Node(newData);
newNode->next = head;
return newNode;
}
I want to delete a linked list recursively. I figured how to do this iteratively but I'm curious on how to do this. So far I have:
void deleteNodeRecursively(LinkedList *list, int value){
Node *curr=list->head;
if (list->head==NULL){
return;
}
else if (list->head->data==value){
Node *x=list->head->next;
delete list->head;
list->head=x;
}
else{
LinkedList *newlist;
newlist->head=list->head->next;
deleteNodeRecursively(newlist,value);
}
}
Where I defined
struct LinkedList{
Node *head;
};
struct Node{
int data;
Node *next;
};
I can remove the head if need be, but I can't figure out how to remove the body or tails and then correctly stitch up the list, let alone do it recursively. How do I proceed? Why won't this work?
EDIT: Removed question marks and replaced with code that I thought would work.
Assuming you have a "correct" constructor and destructor for your Node data.
You would have to track address of the deletion, for which you could pass a double pointer or a reference to pointer.
void deleteNodeRecursively(Node** list, int value){
// ^^^ double pointer to track address withing recursive call
Node *curr= *list ;
if (curr ==NULL){ // Base case for recursion
return;
}
else if ( curr->data==value){ // If node to be deleted is found
*list = curr->next; // Update the address for recursive calls
delete curr; // Delete this current "got" node
}
// Else simple recurse into
deleteNodeRecursively( &(*list)->next, value );
}
Note: This implementation will delete all nodes with data that matches value .
I'm working on a project and I was given this function to complete
void addToEnd(node*& head, string newVal)
Effect: adds new node to tail end of list
Precondition: head is a pointer to first node in the list (list MAY be empty)
Postcondition: list contains one more node
My question is what is the string newVal for?
The value_type of this class is of type DOUBLE so I'm confused what string newVal is for. So I can't set the newVal in the node because it is of two different types.
This is what I have so far. I'm not sure if im going in the right direction.
node *temp = new node;
temp = head;
while(temp->link() != NULL){
temp = temp->link();
}
head->set_link(temp);
I'm not even sure where to use the string in this block of code.
link() returns the member variable node* link_field
set_link() sets the new link to the link_field
Well, we're guessing that they somehow expect you to turn a string into a double with a function like std::stod.
As for your list manipulation code, there's a few problems:
node *temp = new node;
temp = head;
This creates a new node, puts its pointer in temp, then immediately overwrites temp with head, losing (leaking) the new node. Don't do that.
while(temp->link() != NULL){
temp = temp->link();
}
This is close, but might not work. The problem is that you need to keep track of the real node pointer, not a copy.
Normally, in a linked list API using pointers instead of references, the "add node" function looks like:
void addToEnd(node** head, string newVal)
{
while(*head)
head = &((*head)->next);
*head = new node;
(*head)->value = newVal;
(*head)->next = 0;
}
Note that if the list is empty, the passed-in head pointer is altered to point to the new node. If the list is not empty, the last next pointer is altered instead.
The API you're given (i.e. the link and set_link methods) doesn't allow this, because the head pointer is not a node and those functions require a node. So you've got to do it a little differently, namely you have to handle the empty list case separately.
void addToEnd(node*& head, string newVal)
{
// Create the node.
node* newNode = new node;
newNode->value = std::stod(newVal);
newNode->set_link(0);
if(!head) // Empty list?
{
head = newNode;
return;
}
// Find last node.
node* item = head;
while(item->link())
item = item->link();
item->set_link(newNode);
}
I am trying to add and print a new node at the beginning of my linked list. But my code doesn't show the added data while printing in C++.
struct node{
int data;
node *next;
};
void add_begin(node *S, int k)
{
node *T;
T=new (node);
T->data=k;
T->next=S;
S=T;
}
void print(node *S)
{
cout<<"Elements of the node :\n";
while (S->next!=NULL)
{
cout<<S->data<<endl;
S=S->next;
}
cout<<S->data<<endl;
}
I am assuming that you would be calling this function passing in a node which is the head of a list and an int which is the new data and are expecting the node you passed in to be updated to the new node.
Unfortunately that is not what is happening. Inside the function add_begin it has its own pointer to the first node in the list so when you update it with S=T only pointer in the function is updated, not the one you passed in as well.
If you want to update the pointer you pass in you should pass it by reference (void add_begin(node *&S, int k)) or return the new node pointer from the function and assign it the external pointer manually.
// Variables
typedef struct node
{
int value;
struct node *next;
}mynode;
// Globals (not required, though).
mynode *head, *tail, *temp;
// Functions
void add(int value);
// Function to add new nodes to the linked list
void add(int value)
{
temp = (mynode *) malloc(sizeof(struct node));
temp->next=(mynode *)0;
temp->value=value;
if(head==(mynode *)0)
{
head=temp;
tail=temp;
}
else
{
tail->next=temp;
tail=temp;
}
}
// The main() function
int main()
{
head=(mynode *)0;
// Construct the linked list.
add(1);
add(2);
add(3);
return(0);
}
If I only have a pointer to a node, whose value is 3(The Last node as seen in the aforementioned code) , Can we delete it and make a node whose value is 2(aforementioned code) as the last node.
No you can not. Unless you have some reference to previous node. like head pointer. If you have other reference than its pretty much easier. In fact if you don't have any pointers you will loose the list itself
No, but if you know what you are doing, you can modify the last node in-place. Deleting the last node requires access to the second-to-last node, and specifically its link to the last node.
The answer is no.
You can call free on that pointer to the last node, but that just means that the memory occupied by that node is no longer claimed. The data will most likely stay there unchanged for a while. And that means that the next-to-last node's pointer to it is still valid, even though it should not be.
To delete the node in a way that is meaningful to the list, that pointer contained in the next-to-last node has to be nullified. And that can't be done unless that next-to-last node can be accessed, either by a direct pointer to it, or by traversing the list from a preceding node.
You can use a doubly linked list to access the previous node. Or iterate through the entire list.
Yes you can.. Try the following code:
void deleteNode()
{
mynode *temp1;
for(temp1 = head; temp->next!= tail; temp1 = temp1->next);
tail = temp1;
free(tail->next);
}
It will delete the last node.