What the statement inside the parentheses means - c++

Dont understand what the expression in the while statement means below. Please someone explain
while(trans->link){
trans = trans->link;
}

This is a simple linked-list traversal to find the last element of the list. That is, while trans->link is non-zero (i.e., not NULL - past the end of the list), it will move one step farther down the list: trans = trans->link.

-> is the class member accessor for a pointer. Presumably trans is a pointer and trans->link is a pointer of the same type. The above code says "while trans->link is not zero, assign trans to be trans->link, ultimately moving to the end of a linked list.

Let's suppose you have a structure:
struct Element
{
int value;
Element *next;
};
Linked list consists of nodes that are type Element , and it has a pointer to the head of linked list(first node). The next pointer of the last element of a list points to nullptr(if not familiar with linked lists read More Info).
If you wish to traverse the whole list you need to have a Element *temp pointer that will point to the head (because we don't want to lose our head of the list). And then, after visiting one node, we have to move temp to the next element of the node we are currently pointing to(temp=temp->next).
We will stop the traversal until temp reaches nullptr. That's when the while loop will break.
In your case
link=next
trans=temp
Hope it helps.

Related

How to add a linked list to itself?

Considering that this is my function:
void addtoSameList(const List &another){
for (Node *temp = new Node(*head); temp != nullptr; temp = temp -> next){
Node *ptr = other.head;
Node *temp2 = new Node;
temp2->value = temp->value;
while (ptr -> next != nullptr) {
ptr = ptr -> next;
}
ptr->next = temp2;
temp2->next = nullptr;
}
return;
}
where my goal is to append a linkedlist to itself, I do not know exactly what goes wrong.
If, for example, I have a linkedlist called n in the main function, where I then declare:
n.addtoSameList(n);
meaning that &other is going to be pointing at the same node as n, I figured that I would make a new node and deep copy the contents of n.
However, my two outputs are either that I end up in an infinite loop, or that some node ends up getting skipped.
How do I fix this issue?
This code has numerous issues. First, the interface doesn't suggest that the only use is to append a linked list to itself. Nor does it suggest that a deep copy is necessary in any other case.
So, lets adjust the requirements...
You want a member function that will append a copy of a linked list to the existing one. Then the case of self-appending naturally falls out of the problem description.
The approach here would be to step through the linked list that is passed in, carefully copying each node, then re-adjusting the pointers on the main linked list to point at your new node and the pointer in the new node to be set to appear to be the end of the list. This maintains a list invariant as the list is stepped through.
There is a pitfall here though. If you are self appending, you risk creating an infinite loop. So you should find the end node of the passed in list before you start this process and consistently use it to find out if you've gotten to the end of the list. If you maintain a tail pointer, this is trivial. If you don't, it means a list traversal.
Another way would be to simply create a copy first, carefully maintaining the pointer to the first node of the copy. Then just adjust the tail node's next pointer to point at the new list, and then adjust the tail node (if you maintain that pointer in the LinkedList data structure) to point at the tail node of the copy. And that's probably the way you should go. It's cleaner and more efficient. The main drawback is cleanup when doing exception handling. But, at your level, you shouldn't be concerned with that right now.
Here's an alternate approach. Create three pointers: ptrBegin, ptrEnd and ptrNew. ptrBegin points to the beginning of the linked list and traverse the linked list so that ptrEnd and ptrNew point to the last element of the linked list. Then increment ptrBegin until ptrBegin != ptrEnd at the same time copying the data at ptrBegin to a new node at ptrNew->next and increment ptrNew.

delete node from linked list (C++)

I don't understand how this code can delete node, please help!!!
Node* del_place(Node* L, int S)
{
int i=1;
Node *p=L;
while (p!=NULL&&i!=S-1)
{
p=p->next;
i++;
}
p->next=p->next->next;//why can this code delete node in L...
return L;
}
Let's take a look at what the function does. It takes two arguments, the linked list, and the index of the item to be removed.
First, it searches the right node:
p is the first item of the linked list. It starts stepping through the list, untill either, the right index is found (i=S-1) or untill the end of the list is reached (p=NULL).
when it has found the right node, it sets the link to the next item: p-> next, to the next item of the next item.
And now, you can also see the problems in the function:
When an item is removed, the item itself is still in the list, there
is just no more pointer to it, this is a memory leak like molbdnilo said.
When the end of the list is reached (p=NULL), you try to set p->next to NULL, this will cause the program to throw a nullpointerexception.
If p itself is the last item in the list, p->Next will be null, and since you try to call 'Next' on this item, you will also get a nullpointerexception.
The line does not actually delete the Node from the memory. It removes it from the linked list.
The code makes your current Node (p) points to the second Node on the right instead of the first on the right.
Several issues with this code:
Potential memory leak since the Node is not deleted from the memory
you need to do some check before p->next=p->next->next; or you might have some undefined behaviour when p or p->next end up being NULL. e.g. L is NULL, S > size of the linked list...

Deleting the last node in the linked list

Please can you explain to me how this function deletes the last node in a single linked list
void deleend()
{
Node *q;
Node *p;
for (q = head; q != NULL; q = q->next)
{
p=q;
p->next=NULL;
}
delete q;
}
The deletion of the last item of a list is a pretty simple algorithm.
You need to loop throught the whole list until you reach a node with the next pointer equals to NULL. This is your last element, the element you want to delete.
So you need to free the memory allocated by this object and set the next pointer for your previous item to NULL. This is the most important thing since it avoids to get segfaults.
Now, about the code you posted, I see you are doing something pretty bad.. you're declaring *q and *p, then looping throught your list (pointed by a global Node* head, I suppose).
The issue is that with the code in your loop you're unlinking the first item from the linked list and then the loop ends because You're copying the pointer q in p and then setting it's next pointer tu Null which leads to setting q->next to NULL. The first iterations goes ""fine"" leading you to have the first element with next set to Null the second iteration finds the next set to Null and thus it stops.
NOTE: Before posting the code solution I'd like to know if you have pretty clear in mind what the algorithm purpose is, try make an attempt to fix your code, if you can't do it again I'll post the correct algorithm :)

Is it possible to delete the last node in a linked list?

For example, there is an exercise that says:
Write a function to delete a node from a linked list, given only that pointer
And this is the solution:
void deleteNode(Node* toDelete) {
// this function essensially first copies the data from the next pointer
// and then, deletes the next pointer
// However, it doesn't work if trying to delete the last element in the list
Node *temp = toDelete->next; // create a temp, assign to the one after toDelete
toDelete->data = temp->data; // change toDelete's data to the one's after it
toDelete->next = temp->next; // change toDelete's next to the one's after it
delete temp;
temp = nullptr;
}
How can I alter my solution to be able to delete the last element in the linked list, given only the pointer last node?
Obviously you can't; the previous node points to a valid node, and there's no way to change that.
What you could do is add a sentinel node to the end of the list. You would never remove that node, and never use it to store data. Then your solution will work for all data nodes. This doesn't require any changes to the node structure, but does require changes to the way you iterate over the list.
No, it's not possible with a singly-linked list.
The reason is that you need to modify the penultimate node (to make its next pointer null). But there is no way of finding that node from the last node.
In general, you cannot remove a node from a singly-linked list given only a pointer to the node.
What you're currently doing is essentially a "cheat", since you aren't really deleting the node pointed to. You're mutating the list and then deleting the successor of the node pointed to. This makes a difference if some other bit of code somewhere is holding a pointer to that successor when you call this function -- their pointer gets invalidated. So you're removing the data element pointed to, but you aren't removing the node pointed to.
In order to handle deletion of a node in a single linked list like that you would need to modify the node before and after.
+-----+ +----------+ +------+
header----->| |->| toDelete |->| |
+-----+ +----------+ +------+
you would need a pointer to the first element of the list since otherwise it is impossible to do what you want due to the nature of the data structure.
first you find the node before the one you need to delete e.g.
Node* before = header;
for (;before->next != toDelete; before = before->next) {;}
now do before->next = toDelete->next if toDelete is the last node it will be a nullptr otherwise a pointer to the next node
(of course you need to delete what the toDelete points to in both cases)

How to make a linked list in using structs?

I've seen a few topics about linked lists, and I've read enough to glean how to do it generally, but I want to make sure I'm not wrongly interpreting the information I've gathered.
Let's say I have:
struct element
{
int val;
element *next;
};
The element *next is a pointer to an element, which will be used to connect the elements together in order to form the linked list.
I've also gathered that you need to have some kind of "tie off" so you don't lose your list. My professor describes it as a trail of balloons, and if you dont have a "tie off" your list can get lost.
So I start off with creating the "tie off" pointer:
element first;
first -> *next = 0; // or null
This is where I get lost... How do I add to the head of a linked list? Ordering it isn't important at this point, I just need to start with an unordered list, I'll get more complicated later.
Something like this?
element addMe;
addMe -> val = 100;
first -> next = *addMe;
Is that right?
What would I do to add something to a non-empty list?
Thanks for the time!
Edit: This is not homework. We have gone over linked lists, and have done an assignment with them. I did not get a very good grade on the assignment, so I am trying to strengthen my understanding before the next assignment. We will use linked lists again.
Edit2: Thanks!
I do not know if this would be considered "homework" or not. I personally do not think it is, considering I will not be using the code I posted here.
With singly-linked lists, the efficient way to add new elements is putting them at the beginning of the list. For your design, this would be:
element newHead;
newHead.next = &list;
You'll notice that newHead is now the first element, and list no longer represents the whole list. This leads to a more functional programming style, where you are creating new lists all the time (see: the cons function in Lisp).
Procedural languages like C++ generally use some wrapper structure like this:
struct list
{
element * first;
void prepend(element * elt)
{
elt->next = first;
first = elt;
}
}
so list prepends are expressed as changing an existing list instead of creating a new one.
With such an auxiliary structure, it is also trival to keep track of the list size, and keep a pointer to the last element for fast appends. These both come at the cost of a few extra instructions for every list operation.
You generally store a pointer to the first node:
element* first = &first_node; // this "ties" it off
first->val = 5; // set first node value to 5
first->next; // pointer to next node
If your list is empty then first should be set to NULL.
Also, the last node in your list should have next be set to NULL.
you got to have a first pointer or head pointer or whatever you may call it. its the pointer that is NULL when your linked list is empty. But when you add first element to the linked list add that elements node address to the hear/first pointer too. and from the 2nd node onwards append the new nodes address to end of the list (node whose next pointer is NULL) or at the star by changing head/first and then adding the current head to new head's next.
I don't know if such theory has helped. Just follow examples or write your own code. and if you encounter errors post it on SO. i guess linked list , queue, stack , etc are available on all c or c++ books.
or search for linked list in SO.
this might do for a start: Simple C++ Linked List
If you want to add to the head of the list
struct element *el = (element *) malloc(sizeof(struct element));
el->val = 100;
el->next = first;
Now el is the first element, and first is the second.
In your example, you where overwriting the first element next element with a new one. You where cutting the list and inserting your new element as the second element. Everything after first is now off the list (which is also a list, but you can't access it, since you overwrote the pointer to this 3rd element).
To add to the end of the list, iterate
struct element *e;
e = first;
while (e->next !=0)
e = e->next;
// here e is the last element. Allocate a new one and point e->next to it. And set this new one next to 0.