Move head node to end of list - java

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

Related

Circular Doubly Linked List Java - Explanation

at the moment, I am programming a circular doubly linked list and my task is completed, but I have a slight problem in understanding the code 100%.
This is the code:
if (counter == 0) {
startpoint = newNode;
startpoint.next = startpoint;
startpoint.prev = startpoint;
head = startpoint;
currentNode = newNode;
} else {
newNode.prev = startpoint.prev;
newNode.next = startpoint;
startpoint.prev.next = newNode; <- this is, where I have problems
startpoint.prev = newNode;
head = startpoint;
currentNode = newNode;
}
counter++;
}
The first part is completeley clear and just describes, that the first node (if there is no other node) is going to point on itself, when the next or first-method is called. After the else-statement, the first line describes that the first node can point to the second and the second to the previous node, right?
The second line after else just describes, that the last node points onto the first one. The fourth line than describes, that the first node points onto the last node, if the prev-method is called and so the circle is closed. But what exactly does the third line describes? The code definitely works.
Thank you for your time!
Greets
Dominik
Your list is circular.
startpoint.previs the element before the startpoint, so it's the last element of the list.
Let's take an example, this is your list: A>B>C, you try to add D.
This line: startpoint.prev.next = newNode; will link the current last element (C as A.prev == C) to your new element. (C.next = D)
this line startpoint.prev = newNode; will set the new element as the last element of the list (A.prev = D).
The code inserts newNode just before startpoint. The 3rd line of the else statement simply updates the node before the startpoint so that it's next field references the new node.
To make it more clear, one can rewrite the line like this:
Node nodeBeforeStarpoint = startpoint.prev;
nodeBeforeStartpoint.next = newNode;

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

insert an element at the end of one-dimensional Linked-list [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I'm struggling with inserting an new element at the end of Linked-list. The problem appears at the while-loop "NullPointException". Could anybody help?
// Node head = null;
#Override
public void add( T newvalue ) {
Node newNode = new Node (newvalue);
newNode.next = head;
head = newNode;
}
Your code is not correct for adding to the tail of a linked list. A linked list should add a new node at the END of the current or last node. Since you only show that head is a node and more than likely this is a single pointer node, let's assume that head is what will point to the end of the node (you can change the name to tail). Your code would need to look at the last node (head in this case), and add the new node to it, then update the reference to the new node.
// Node head = null;
#Override
public void add( T newvalue ) {
Node newNode = new Node (newvalue); //define new node
if(head !=null){//make sure what you are pointing to exists
head.next = newNode; // set the next point to newNode
head = newNode; //change the reference to your tail (called head here)
} else{
head = newNodel; //if doesn't exist, just point to new node
}
}
That's the jist of what you want.
Honestly, you will want a head node and a tail node. Without the head node always pointing to the head, you will not be able to traverse the list. Head should point to the first node always and tail should point to the last node. At first, head and tail will point to the same null or 1st node. Then you move tail in the add function.

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.

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