How to understand head->next->next = head; for reverse single list by Recursion? - algorithm

A signle link list, i want revese it by recursion. but i don't understand the meaning of this line head->next->next = head;.
why there need head->next->next?
struct Node{
int data;
Node* next;
};
Here is the implement code:
Node* reverseByRecursion(Node *head)
{
if(head == NULL || head->next == NULL)
return head;
Node *newHead = reverseByRecursion(head->next);
head->next->next = head;
head->next = NULL;
return newHead;
}

Let me work with this list.
reverseByRecursion(node1) is called.
Neither node1 nor node1->next is NULL, so newHead = reverseByRecursion(head2); is called.
Neither node2 nor node2->next is NULL, so newHead = reverseByRecursion(head3); is called.
head3->next is NULL, so head3 is returned from reverseByRecursion(head2).
head = node2 and head->next = node3, so head->next->next = head; will set node3->next to node2.
head->next = NULL; will set node2->next to NULL. (image 2)
newHead, which is node3, is returned from reverseByRecursion(head2).
head = node1 and head->next = node2, so head->next->next = head; will set node2->next to node1.
head->next = NULL; will set node1->next to NULL. (image 3)
newHead, which is node3, is returned from reverseByRecursion(node1).
Now the list is reversed with having node3 as the head.
image 2
image 3

try to understand it this way, .next actually meant to change the arrow pointing to the next value. So
head.next.next = head
means adding an arrow from the next next position and point it back to head
Hope this is more intuitive to understand

Your base case says that if there are no more elements, then the current node becomes the head of the list.
The head->next->next = head line means that the next node is being reused with its pointer pointing backward (in the opposite direction as before). Since the node used to be the NEXT node after the current node, it becomes the PREVIOUS node before the current head, and its next pointer therefore ought to point to the current node ("head").

Related

Linked List - Keeping track of each node

I found an algorithm to loop through a sorted linked list and remove the duplicate. I wrote it, it works.
Still, I don't understand how can this work. In the end of the loop, to move forward into the while loop, we do this :
currentNode = nextNode
How can this not erase the current node ? Why does the linked list is still here ? It feels every node is erased each time by the next, isn't it ?
class LinkedList {
constructor(value) {
this.value = value;
this.next = null;
}
}
function removeDuplicatesFromLinkedList(linkedList) {
let currentNode = linkedList;
while(currentNode !== null){
let nextNode = currentNode.next;
while(nextNode !== null && nextNode.value === currentNode.value){
nextNode = nextNode.next;
}
currentNode.next = nextNode
currentNode= nextNode
}
currentNode = linkedList;
return linkedList;
}
exports.LinkedList = LinkedList;
exports.removeDuplicatesFromLinkedList = removeDuplicatesFromLinkedList;
In fact, linkedList is never overwritten, so the initial list isn't damaged (because when removing duplicates, the first one is kept, only the following are removed).
Then, currNode is just the current pointer, to the current node. Assign a new value to it don't delete the previous node, since it's still referenced through the list head linkedList.
What is really missing is the free instruction on deleted node - this algo rely on a garbage collector to work without a memory leak.
Let's do this by an example:
2 -> 3 -> 3 -> 4
Initially currentNode == 2. In the first iteration of the loop nextNode == 3, which is the next node to current node. The inner while loop doesn't run since currentNode.value isn't equal to nextNode.value. So we hit:
currentNode.next = nextNode
currentNode= nextNode
This sets the next node of currentNode to NextNode. So, nothing changes. Then we move current node one forward: currentNode = nextNode
In the next iteration though, nextNode == 3, while currentNode == 3 too. Now the inner while loop runs one iteration and moves nextNode to 4 and breaks since they aren't equal anymore. Then, currentNode.next is set to nextNode, which was 4, and after nextNode is assigned to currentNode.
Since these are all pointers to nodes, nothing is being erased. Just the duplicate values are removed from the chain of linked nodes.

How do I understand this piece of code to reverse a linked list with recursion?

Node* reverse(Node* node)
{
if (node == NULL)
return NULL;
if (node->next == NULL) {
head = node;
return node;
}
Node* node1 = reverse(node->next);
node1->next = node;
node->next = NULL;
return node;
}
I can understand first two if statements but the sentence of Node* node1 = reverse(node->next); runs, I think it will call it self and then execute first two if statements. So when the last three lines node1->next = node;node->next = NULL;return node; execute?
A bit confused here >_<
It is recursion.
Function calls itself with smaller sublist, reverse it, then glues reversed one with current node.
A -> B...Z
separate A node and list B...Z
reverse B...Z
Z...B
append A node
Z....B -> A

Deleting nodes greater than specified value from linked list

Given an integer value and a pointer to the head of the linked list, how to delete all the nodes from the list that are greater than the specified value?
e.g.
List : 10->34->11->19->26->55->17
value: 19
output: 10->11->17 (All the nodes greater than 19 needs to be removed)
(Edge case)
List : 10->3->17->5->2->14->7
value: 9
output: 3->5->2->7 (All the nodes greater than 9 needs to be removed)
I am not looking for the exact code but just an algorithm to solve this!
private static Node removeNodes(Node start, int x) {
if(start == null) return start;
if(start.data > x && start.next == null) return null;
//find first head node
Node cur = start;
Node prev = null;
//4,5,3,2,1,6 --- where x = 2
while(cur != null && cur.data > x) {
prev = cur;
cur = cur.next;
}
if(prev != null) prev.next = null;
Node newHead = cur;
while(cur.next != null) {
if(cur.next.data > x) {
cur.next = cur.next.next;
} else {
cur = cur.next;
}
}
return newHead;
}
first assign a temporary node to the start node
Then you have three cases in linked list..
if the desired node at the first position then make start to be equal start->next and delete temp node
if it is in the middle make another node to be stopped right before temp and make the next of that node to be equal the next of temp and then delete temp
if it is at last position make the next of the node before it to be equal to nullptr and that is it.
It can be solved using two pointers, previous and current,I guess this solution work.
public static ListNode removeNode(ListNode head,int value){
//removing every element whose Node value is greter than given value
if(head==null) { return head;}
ListNode current=head;
ListNode previous=new ListNode(0);
previous.next=current;
while(current!=null){
//System.out.println("current value; "+current.val);
if(current.val>=value){
if(current.next==null){
current=null;
}
else {
current=current.next;}
previous.next=current;
}
else {
previous=previous.next;
current=current.next;
}
}
return head;
}
Consider the picture here .Suppose we have to delete the node which is greater than 8 and we have Head Pointer pointing to head of the list.First we will take two pointers Prev and temp both points to head initially.Then through the pointer we will traverse the list and keep track the current and prev pointers in temp and Prev.If current number is greater than 8 Prev will point to the next node pointed by temp and temp node will be deleted.By traversing all the node and following this rule you can delete the specified node of the list....
I hope you got the point........

is wikipedia iterative postorder tree traversal pseudo code wrong?

Here is the pseudo code that wikipedia gives for iterative postorder tree traversal.
iterativePostorder(node)
parentStack = empty stack
lastnodevisited = null
while (not parentStack.isEmpty() or node ≠ null)
if (node ≠ null)
parentStack.push(node)
node = node.left
else
peeknode = parentStack.peek()
if (peeknode.right ≠ null and lastnodevisited ≠ peeknode.right)
/* if right child exists AND traversing node from left child, move right */
node = peeknode.right
else
visit(peeknode)
lastnodevisited = parentStack.pop()
It is pretty straight forward, and I have implemented it in Java. But it does not work, the problem is that every time it visits the most left leaf and return to its parent, it will add that left leaf again into the stack in next iteration. This causes an infinite loop. Is my method incorrect or the wikipedia version is wrong?
public static List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if (root == null) return res;
Stack<TreeNode> s = new Stack<TreeNode>();
TreeNode lastVisitedNode = null;
TreeNode curr = root;
int i = 0;
while (curr != null || !s.isEmpty()) {
if (curr != null) {
System.out.println("push " + curr.val);
s.push(curr);
curr = curr.left;
} else {
curr = s.peek();
if (curr.right != null && lastVisitedNode != curr.right) {
curr = curr.right;
} else {
res.add(curr.val);
System.out.println("pop " + curr.val);
lastVisitedNode = s.pop();
}
}
System.out.println(s);
System.out.println(res);
if (i>8) break;
else i++;
}
return res;
}
The wikipedia version is wrong for the exact same reason as you've explained it.
Here is a probably better pseudo-code, from geeksforgeeks
1.1 Create an empty stack
2.1 Do following while root is not NULL
a) Push root's right child and then root to stack.
b) Set root as root's left child.
2.2 Pop an item from stack and set it as root.
a) If the popped item has a right child and the right child
is at top of stack, then remove the right child from stack,
push the root back and set root as root's right child.
b) Else print root's data and set root as NULL.
2.3 Repeat steps 2.1 and 2.2 while stack is not empty.
You will have to add extra code to check if the node right child is null in 2.1.a though.
The wikipedia pseudocode is not wrong. They use two different variables: node and peekNode, while you only use curr for both. Node == null refers to the case when there is no more of a left branch left to explore, so we can stop pushing and instead investigate the next element in the stack. You can either revert to using two different variables, or you make the following fix in your code:
Since you reassign curr to a non-null value everytime you investigate the stack, you need to reset curr to null after you visit your node. (Because the state that still no more left branch left to explore is still unchanged).
The wikipedia pseudocode doesn't have to do this because their node value remains null.
Here is my code which gives a perfect answer:
var currentNode = this.root()
var previousNode = null
while(!nodeStack.isEmpty() || currentNode) {
// If there is a node on which the recursive call is made, we have a subtree to explore. If this is null, we have to backtrack and do a callback.
if (currentNode) {
nodeStack.push(currentNode)
previousNode = currentNode
currentNode = currentNode.leftChild
} else {
currentNode = nodeStack.peek()
if (currentNode.rightChild && previousNode != currentNode.rightChild) {
currentNode = currentNode.rightChild
} else {
callback(currentNode)
currentNode = null
previousNode = nodeStack.pop()
}
}
}

Swap the head of the linked list

I had heard this question from my friend who attended an interview recently:
Given the head of the linked list, Write a function to swap the head with the next element in the linked list and return the pointer to the new head.
Ex:
i/p: 1->2,3,4,5 (the given head is 1)
o/p: 2->1,3,4,5
Assuming
struct node {
struct node *next;
};
struct node *head;
then the solution might look something like
struct node *next = head->next;
if(next == NULL) return head; // nothing to swap
head->next = next->next;
next->next = head;
head = next;
return next;
struct node* head;
struct node *tmp1,*tmp2;
tmp1=head; // save first node pointer
tmp2=head->next->next; // save third node pointer
head=head->next; // Move Head to the second node
head->next=tmp1; // swap
head->next->next=tmp2; // Restore the link to third node

Resources