Bug while Swapping a LinkedList - java

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

Related

Algorithm: Merge Sort with linked list missing items

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();

Move head node to end of list

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)
}

Doubly Linked List

I've been trying to figure out how to reverse the order of a doubly-linked
list.I've recently made an account on hackerrank and this was my 10th problem.
It took me 1 hour to figure out the solution (I used pen and paper and tried
many times) and finally it passed as correct.
After that, I saw some answers submitted my some other folks.Their code was
very small in length in comparison to mine or you think my answer is also okay.
I have no one to ask to so I came here...
I feel dumb when I see that.Can I improve it in future??
(forgive me if you think this is a dumb
question)
Node Reverse(Node head) {
Node prevNode = null;
Node NextNode = null;
Node m = head;
Node upComingNode = null;
Node temp = head;
if(head == null){
return head;
}
else{
while(temp!=null){
NextNode = temp.next;
temp.next = prevNode;
m.prev = upComingNode;
prevNode = temp;
upComingNode = prevNode.next;
m = temp;
temp = NextNode;
}
head = prevNode;
}
return head;
}
I am not sure what language you are working in, but to reverse a doubly linked list you, in brief, you want to swap your next and prev nodes for each node. This can be done fairly shortly and the pseudocode is below:
while(currNode != tail){
currNode.nextNode = tempNode
currNode.nextNode = currNode.prevNode
currNode.prevNode = tempNode
currNode = currNode.prevNode
}
Note that we set the next node to iterate on as the previous node, since the previous node is actually pointing to the next node now that we made the switch.

JAVA Linked List :method to insertLast

I have my code as following:
Node current=head;
if(current==null)//check
else{
while(current.getNext()!=null)
current=current.getNext(); //loop through to find the last node in the list
}
//if I find it then connect it with my newNode(add)
Node add=new Node("A");
current.setLink(add);
add.setLink(null);
But it does not work, I drawn a diagram but still have no idea what`s wrong with it.
the line
if(current==null) //why do you check if you don't have any statements afterwards?
this solution is for singly linked list:
public static Node addLast(Node head, Object x) {
// save the reference to the header so we can return it.
Node ret = head;
// check base case, head is null.
if (header == null) {
return new Node(x, null);
}
// loop until we find the end of the list
while ((head.next != null)) {
head = head.next;
}
// set the new node to the Object x, next will be null.
head.next = new Node(x, null);
return ret;
}

Circularly linked list remove tail without loop

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.
}

Categories