Adding nodes in an Unordered Linked List - c++

I just want to know the difference between these two lines. listData is head by the way.
temp->next = listData;
and
listData = temp->next;
Here is the full code for adding a node to an unordered linked list
NodeType* temp;
temp = new NodeType;
temp->data = item;
temp->next = listData;
listData = temp;
length++;
So if I did listData = temp->next instead
of temp->next = listData what would happen or can somebody explain in simplest terms what it means. Everytime I see the -> on the right or left side it gets me confused. Thank you!

The -> simply indicates that you are accessing a pointer reference, nothing more and nothing less.
When you see an equal sign, it means whatever is on the right side is assigned to the left side (unless you override the equal sign), which you normally wouldn't do.
temp->next = listData
You are setting the listData as the next of temp.
listData = temp->next
You are setting next of temp as listData
Since you are adding a node named temp to a LinkedList, you would want the former. Think of a linked list and you are adding a node temp between two nodes A and B. You would:
Set next of A to temp
Set next of temp to B
The latter of this process is what temp->next = listData is doing. (I'm assuming listData is the rest of the linked list after and including B.

Related

how can I reverse my Linked list . I wrote following code but this is giving only first node's data as output

Node *reverse(Node *head)
{
Node *answer = NULL, *p = head, *address = NULL;
while (p != NULL)
{
address = p;
address->next = answer;
answer = address;
p = p->next;
}
return answer;
}
In order to reverse a singly linked list, you need to keep one node in memory to be able to relink backwards.
It could look like this:
Node* reverse(Node* head) {
if(head) { // must have at least one node
Node* curr = head->next; // head + 1
head->next = nullptr; // this will be the new last node
Node* next; // for saving next while relinking
while(curr) { // while curr != nullptr
next = curr->next; // save the next pointer
curr->next = head; // relink backwards
head = curr; // move head forward
curr = next; // move curr forward
}
// head now points at the new start of the list automatically
}
return head;
}
Demo
I wrote following code but this is giving only first node's data as output
Because, in reverse() function, you are breaking the link of first node from rest of the list and returning it.
Look at this part of code:
address = p;
address->next = answer;
answer = address;
p = p->next;
In first iteration of while loop this is what happening:
Pointer address will point to head of list (as p is initialised with head) and, in the next statement, you are doing address->next = answer (note that answer is initialised with NULL). So, address->next is assigned NULL. Both, pointer p and pointer address are still pointing same node. After this, you are doing p = p->next, this will assign NULL to p because p->next is NULL. As, p is NULL, the while loop condition results in false and loop exits and function end up returning the first node.
You should assign p to its next before assigning answer to address->next, like this:
while (p != NULL)
{
address = p;
p = p->next; // moved up
address->next = answer;
answer = address;
}
Suggestion:
In C++, you should use nullptr instead of NULL.
Reversing a linked list, in essence, is pretty much flipping the arrows:
Original: A->B->C->D->null
Intermediate: null<-A<-B<-C<-D
Reversed: D->C->B->A->null
void reverseList(void)
{
Node *prev = nullptr;
Node *curr = head;
while (curr)
{
Node *nxt = curr->next;
curr->next = prev;
prev = curr;
curr = nxt;
}
head = prev;
}
The crux of the solution will be to use the previous and current node strategy to loop through the list. On lines two and line 3, I set the prev to null and curr to the head respectively. Next, I set the while loop, which will run until curr is equal to null or has reached the end of the list. In the 3rd and 4th lines of the body of the while loop, I set prev to curr and curr to nxt to help me move through the list and keep the traversal going while keeping track of the previous and current nodes.
I am storing the next of the current node in a temporary node nxt since it gets modified later.
Now, curr->next = prev is the statement that does some work. Flipping of the arrows takes place through this statement. Instead of pointing to the next node, we point the next of the current node to the previous node.
Now, we need to take care of the head node only. On the last line, head=prev, prev is the last node in the list. We set the head equal to that prev node in the list, which completes our code to reverse a list.
Suppose you have any trouble visualizing the algorithm. In that case, you even have the privilege to print the data stored in the current and previous nodes after each line in the while loop for a better understanding.
Hope this helps getting the gist of how we reverse a linked list.

Sorted Linked List of structs where a struct gets lost

I can't figure out where my logic goes astray in the following lines of code. The linked list is at nodes inside of a Binary Search Tree. Below is my function for sorting the linked list by strings using the compare function
void addNewLLObj(TreeNode *tNode, int ranking, string title, int year, float rating){
LLMovieNode* newNode = new LLMovieNode(ranking, title, year, rating);
LLMovieNode* crawler = tNode -> head;
LLMovieNode* prev = NULL;
while(crawler != NULL){
if(crawler->title.compare(title) > 0){ // checks if the current nodes title is larger than insert title
if(crawler == tNode->head){
newNode->next = crawler;
tNode->head = newNode;
}
else{
prev->next = newNode;
newNode->next = crawler;
}
}
else if(crawler->next == NULL){
crawler->next = newNode;
newNode->next = NULL;
}
prev = crawler;
crawler = crawler->next;
}
}
If I give title strings "Dccc", "Daaa", "Dfff", "Dzzz", "Deee" in that order
I will lose the "Dfff" string when I print the linked list. I am sure my linked list traversal is correct. I just can't figure out where the logic is wrong. I am not sure if I am overwriting "Dfff" somewhere or If I have a memory leak.
Your loop always runs to the end of the list. Even after it found where to insert the new node. This can cause you to add the new node multiple times, causing some of your nodes to disappear from the list.
The solution is simple: Add a break in your code to break out of the loop after adding in newNode.

how to get head of the list after traversal in Linked lists?

I have traversed a linked list and ended up reaching NULL in head in between I modified some elements in head. How do I get back the head pointer with those modifications.
Node* temp=head;
while(head&&head->next){
head=head->next->next;
}
I want linked list to be modified into new one with alternate nodes. So after this how can I get back the new head pointer.
EDIT:
ListNode* temp=head,*new1=head;
while(head!=NULL&&head->next){
new1->next=head->next->next;
head->next=head->next->next;
new1=new1->next;
}
//temp=head;
return new1;
I think what you meant to do is:
Node* temp = head;
while(temp && temp->next){
temp = temp->next->next;
}
That way, you always have the head.
One way is to use a different pointer to traverse the list, and leave head alone.
Another way is to restore head after you are done. Your code seems to indicate this is possible, since you have stored head in temp before you entered the loop.
head = temp;
new1 = temp;

Return a pointer to a sorted list; linked list in C++

i want this function sortPair to take 2 Node pointers and return a pointer to a list of the 2 elements sorted alphabetically. The code below is what I have so far. If someone could let me know where I went wrong, that would be great.
struct Node{
string val;
Node* next;
};
Node* sortPair (Node* p1, Node* p2){
//Assert that neither pointer is null
assert(p1!=NULL);
assert(p2!=NULL);
Node* head=NULL;
Node* current=NULL;
Node* last = NULL;
current = new Node();
if(p1-> val >p2-> val) //If p1->val comes before p2->val in the alphabet
{
current->val = p1->val;
head = current;
last = current;
current = new Node();
current -> val = p2->val;
last = current;
last ->next = NULL;
}
else
{
current->val = p2->val;
head = current;
last = current;
current = new Node();
current -> val = p1->val;
last = current;
last ->next = NULL;
}
return head;
}
A linked list is just a series of nodes that are linked by each element having a pointer to the next one.
From your code, it seems like you do not want to make a list of the two nodes, but rather insert a node into a list that already exists.
If all you want to do is to make a linked list of the two nodes that are there, then set the one with the lower or higher value, depending on how you sort them, to point at the other one. For example, if you are sorting from smallest to biggest, set the smallest node's next pointer to point to the bigger one and return the pointer of the smallest one.
If you want to add one of the nodes into a list of nodes, then you must loop through the list until you find one that is larger or smaller than the node you want to insert. I recommend using a while loop.
If you want to merge two lists, then you must make a new loop that inserts each element of one list into the other list.
There is no need to make a new node for any of this, just use the ones you have and change the next pointers.
Hope this helps.

Remove all nodes in linked list

I have a linked list contains 3 nodes like the image shown:
There is a head pointer and temp1 pointer point to the front of the list, and tail point points at the end of the list.
I want to remove all the nodes, and change it back to its original initial form ( tail = NULL, head = first_node , but the first node doesn't have any value in the data and next field).
Because I want to start putting up some new values in it. To remove all those data, is this code going to remove nodes inside this linked list and left with the first node with no values in data and next field?
This code is in C++:
while(temp1!=tail)
{
temp1 = temp1->next;
if(temp1->next == tail)
{
tail=temp1;
temp1 = temp1->next;
free(temp1);
}
}
But then, does this mean only the last node will be deleted? are there any way to delete all the nodes except the first one?
To delete all nodes except the first node, you can try below code.
temp1 = head->next;
while(temp1!=NULL) // as I am considering tail->next = NULL
{
head->next = temp1->next;
temp1->next = NULL;
free(temp1);
temp1 = head->next;
}
This will delete all nodes except first one. But the data with the first node will remain as it is.
Disclaimer: I assume it's only for learning purposes and in real-world scenario you would use std::list<> or similar container.
For single-linked list, you can just drop all this burden an let the stdlib manage the pointers:
class Node {
std::unique_ptr<Node> next;
};
You can safely use .reset() method to make operations on the list:
Given current_ptr, the pointer that was managed by *this, performs the following actions, in this order:
Saves a copy of the current pointer old_ptr = current_ptr
Overwrites the current pointer with the argument current_ptr = ptr
If the old pointer was non-empty, deletes the previously managed object if(old_ptr != nullptr) get_deleter()(old_ptr).
From http://en.cppreference.com/w/cpp/memory/unique_ptr/reset.
And that's pretty much what you would do when deleting. I believe you can also use unique_ptr::swap(), to easily manipulate your nodes.
Instead of free, C++ uses delete function.
Check the link to have deep knowledge about all kind of operations(including recursive or iterative delete) on linked lists.
temp1 = head->next;
while(temp1!=NULL) // as I am considering tail->next = NULL
{
head->next = temp1->next;
temp1->next = NULL;
free(temp1);
temp1 = head->next;
}
The logic for this would be more correct if it is this way.
After the statement
free(temp1);
Add the condition
if (head -> next != NULL)
temp1 = head->next;
Since after deleting the last node there is no point in reassigning the address of head pointer to temp1.