Here I am trying to Swap the Head and tail of a singly Linked list
public void reversePI() {
Node N1 = this.tail;
Node Helper = this.head.next;
this.tail = this.head;
this.tail.next = null;
this.head = N1;
this.head.next = Helper;
this.display();
}
Here is the further Approach for the above function to explain my way of thinking.
Let us assume we have a Link list as
4k(adress) 1(data)-->5k(adress) 2(data)-->6k(adress) 3(data)-->7k(adress) 4(data)-->null
we have a code
now when the first line executes
N1= 7k(adress) 4(data)
Helper=5k(adress) 2(data)
this.tail=4k(adress) 1(data)
at this point the list should be
5k(adress) 2(data)-->6k(adress) 3(data)-->4k(adress) 1(data)-->5k(adress) 2(data)
now we set the tail as null to break the initial link
this.tail.next = null;
5k(adress) 2(data)-->6k(adress) 3(data)-->4k(adress) 1(data)-->null
now this.head = N1;
7k(adress) 4(data) 5k(adress) 2(data)-->6k(adress) 3(data)-->4k(adress) 1(data)-->null
after this this.head.next = Helper; line will establish the link and
7k(adress) 4(data)--> 5k(adress) 2(data)-->6k(adress) 3(data)-->4k(adress) 1(data)-->null
is my Approch correct or is there something I am missing that leads to generating an infinite output while running the display method -->
public void display() {
Node current = this.head;
while (current != null) {
System.out.print(current.data + " ");
current = current.next;
}
}
You forgot to handle the second last node's next, it should point to the new tail, but it is still pointing to the old tail which is the new head. This results in a loop: head -> ... -> secondLastNode -> head
I am trying to sort my linked list with merge sort. The list is actually sorted but it is kind of missing first item(s).
Merge sort functions:
public Node mergeSort(Node head) {
if (head == null || head.next == null) {
return head;
}
Node middle = middleElement(head);
Node nextofMiddle = middle.next;
middle.next = null;
return merge(mergeSort(head), mergeSort(nextofMiddle));
}
public Node merge(Node left, Node right) {
Node temp = new Node();
Node newHead = temp;
while (left != null && right != null) {
if (left.info <= right.info) {
temp.next = left;
temp = left;
left = temp.next;
} else {
temp.next = right;
temp = right;
right = temp.next;
}
}
temp.next = (left == null) ? right : left;
return newHead;
}
public Node middleElement(Node head) {
if (head == null) {
return head;
}
Node slow = head;
Node fast = head;
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
So I printed the list to the screen using traverse:
public static void main(String[] args) {
MyLinkedList mll = new MyLinkedList();
mll.insert(3);
mll.insert(5);
mll.insert(9);
mll.insert(1);
mll.insert(8);
mll.insert(7);
mll.insert(2);
mll.mergeSort(mll.head);
mll.traverse();
}
I have result like this:
1 and 2 missing!
After checking, i noticed that the "tail" of the linked list value is still 2. I don't know why can someone help?. I'm really new to programming so sorry for any inconvenience. Thank you for reading!
You're not far from a correct solution. I was able to get a working sort by adding 1 line and changing 3.
Your merge isn't doing what you think it is.
Allocating a false head node (what you call temp, not a good choice of name; try falseHead) is a fine idea. Then falseHead.next is the true head. That's what you'll finally return as the sorted list. Note that initially it's null, which is what you'd expect.
What you're missing is a variable tail to reference the current last node in the merged list. Since there is initially no last node at all, this should be initialized equal to falseHead. Consequently, when you append the first element to the tail of the current result by setting tail.next, you'll also be setting falseHead.next, i.e. creating the head element. It all works out.
Now, what is the logic for, say, removing the current head of the right list and appending it to the merge result? It's just 3 steps:
Do the append operation by making tail.next the current head of right.
Update tail to tail.next.
Remove the head of right by updating right to right.next.
Of course the left side is similar.
Good luck. You're close.
You have a couple problems that I can see. One, mentioned by #rcgldr, in the comments is that you merge method is returning the temp node newHead, but that node was no value and is not part of your graph. You need to return it's child newHead.next.
The other problem is that you never reset the head of your list. So after all the sorting, the head of mll still points to the original head, which in this case is 3. So when you traverse the list you skip 1 and 2. I'm not sure what your linked list class looks like but something like this should be close -- just assign the final node returned by mergeSort to the head of the list. Then when you traverse you should be starting in the right spot:
mll.head = mll.mergeSort(mll.head);
mll.traverse();
I am really struggling trying to create a code that takes the head of a singly linked list and moves it to the end of the list. I'm just beginning to get frustrated because I'm so confused so I came here. If anyone could help me out and explain where to even begin with this I would greatly appreciate it. This is what I had, even though it's an infinite loop and not the right thing I thought maybe it could be a start. Thanks for any input.
public void flip(Node head, Node tail){
Node temp = head;
head = temp.next;
head.next = null;
tail.next = head
}
If you already have head and tail as the input, you could process as :
Move 'head' to point to its current next
head = head.next;
Make sure the current head's next is initialized to null. (since it would be the last element now)
temp.next = null; // where temp is a new Node with head's data
Point 'tail.next' to this head's node
tail.next = temp
Something like this :
public void flip(Node head, Node tail){
Node temp = new Node();
temp.data = head.data;
temp.next = null; // (2)
tail.next = temp; // (3)
head = head.next; // (1)
}
I tried to implement a circularly linked list and I had read that the complexity of removing the tail (which has a direct reference) is O(1). However I can't get rid of the tail reference without looping and resulting in a complexity of O(n) and so I was wondering if this is at all possible without looping?
remove = tail;
prev = temp = tail.getNext();
do
{
prev = temp;
temp = temp.getNext();
}
while(!temp.getNext().equals(tail.getNext()));
prev.setNext(temp.getNext());
size--;
return remove;
Note: prev, temp, removeare local and tail is the tail of the list and first instance of tail.getNext() is the head.
I had tried the below as well but it does not work as the node before tail still points to tail and the reference isn't removed. I know that I need make the tail's previous point to the head in order to remove the tail and the above code does this, but I'm just unsure how to do this and if it's possible without looping through the list..
remove = tail;
tail= lastNode.getNext();
size--;
return remove;
In a circularly linked list every node has a previous and next. There is the head pointer to the first node, and its previous is the tail node, whose next is the head node.
So
Node removeTail() {
if (head == null) {
return null;
}
Node tail = head.previous;
Node newTail = tail.previous;
newTail.next = head;
head.previous = newTail;
if (head == tail) {
head = null;
}
--size;
return tail; // If so desired.
}
Given the current node, how can I find its previous node in a Singly Linked List. Thanks. Logic will do , code is appreciated. We all know given a root node one can do a sequential traverse , I want to know if there is a smarter way that avoids sequential access overhead. (assume there is no access to root node) Thanks.
You can't.
Singly-linked lists by definition only link each node to its successor, not predecessor. There is no information about the predecessor; not even information about whether it exists at all (your node could be the head of the list).
You could use a doubly-linked list.
You could try to rearrange everything so you have the predecessor passed in as a parameter in the first place.
You could scan the entire heap looking for a record that looks like a predecessor node with a pointer to your node. (Not a serious suggestion.)
If you want to delete the current node, you can do that without finding previous node as well.
Python Code:
def deleteNode(self, node):
node.val = node.next.val
node.next = node.next.next
# Delete Node in a Linked List
Walk through the list from the beginning until you meet a node whose next link points you your current node.
But if you need to do this, perhaps you oughtn't be using a singly linked list in the first place.
Your only option for a singly-linked list is a linear search, something like below (Python-like pseudo code):
find_previous_node(list, node):
current_node = list.first
while(current_node.next != null):
if(current_node.next == node):
return current_node
else:
current_node = current_node.next
return null
Assuming that you're talking about a forward singly linked list (each node only has a pointer to 'next' etc) you will have to iterate from the start of the list until you find the node that has 'next' equal to your current node. Obviously, this is a slow O(n) operation.
Hope this helps.
Keep two-pointer(curr, prev) initially both will point to head of the list.
do a loop on the list until you either reach at the end of the list or at the required node.
for each iteration move curr node to the next of it but before moving to next store its pointer in prev pointer.
prev = curr; // first store current node in prev
curr = curr->next // move current to next
at the end of loop prev node will contain previous node.
getPrev(head, key) {
Node* curr = head;
Node* prev = head;
while(curr !=null && curr->data==key){
prev = curr;
curr = curr->next
}
return prev
}
Example:
list = 1->5->10->4->3
We want prev node of 4 So key = 4 and head point at 1 here
initially:
temp will point to 1
prev will point to 1
iteration 1:
First, assign prev=temp (prev point to 1)
move temp; temp->next (temp point to 5)
iteration 2:
First, assign prev=temp (prev point to 5)
move temp; temp->next (temp point to 10)
iteration 3:
First, assign prev=temp (prev point to 10)
move temp; temp->next (temp point to 4)
iteration 4:
temp->data == key so it will return out of loop.
return prev node
This is some kind of hack which I found out while solving the problem(Delete every even node in a list)
internal void DeleteNode(int p)
{
DeleteNode(head, p);
}
private void DeleteNode(Node head, int p)
{
Node current = head;
Node prev = null;
while (current.next != null)
{
prev = current;
current = current.next;
if (current.data == p)
{
prev.next = current.next;
}
}
}
Now here, in prev you assign the current and then move the current to next thereby prev contains the previous node.
Hope this helps...
You can do it like this.. you can replace the value of current node by value of next node.. and in the next of 2nd last node you can put null. its like delete a element from a string. here is code
void deleteNode(ListNode* node) {
ListNode *pre=node;
while(node->next)
{
node->val=node->next->val;
pre=node;
node=node->next;
}
pre->next=NULL;
}
Use a nodeAt() method and pass the head,size and the index of the current node.
public static Node nodeAt(Node head,int index){
Node n=head;
for(int i=0;i<index;i++,n=n.next)
;
return n;
}
where n returns the node of the predecessor.
Here is a small trick with linear search: just pass in the node or its position whose previous node you are searching for:
private MyNode findNode(int pos) {
//node will have pos=pos-1
pos-- = 1;
MyNode prevNode = null;
int count = 0;
MyNode p = first.next; // first = head node, find it however you want.
//this is for circular linked list, you can use first!=last for singly linked list
while (p != first) {
if (count == pos) {
prevNode = p;
break;
}
p = p.next;
count++;
}
return prevNode;
}
We can traverse through the LinkedList using slow and fast pointers.
Let's say
fast pointer fast = fast.next.next
slow pointer slow = slow.next
Slow pointer will be always a previous of the fast pointer, and so we can able to find it.
It can possible to deleteNode if only given node not root or head. How ?
It can achieve by reversing value in node
4-> 2 -> 1 -> 9 given 2 as node to remove. as above other can't access previous node which is correct because singly linked list we don't store predecessor. What can do is swap value of next of give node to given node and change link to next of next of give node
nextNode = node.next // assigning given node next to new pointer
node.val = nextNode.val // replacing value of given node to nextNode value
node.next = nextNode.next // changing link of given node to next to next node.
I tried this approach and its working fine.
assuming you are using forward singly linked list your code should look like
while(node)
{
previous = node
node = node.next
// Do what ever you want to do with the nodes
}