linked list reverse is not working ....? - java

I know it is a minute code. I can't understand why my linked list reversal is not working.
Can some one help fix me my reverse method in the below code.
//Reverse a single linked list
public Node reverse()
{
return reverse(root);
}
private Node reverse(Node node)
{
Node previous = null;
Node current = node;
Node forward;
while (current != null)
{
forward = current.next;
current.next = previous;
previous = current;
current = forward;
}
return previous;
}
Any input on this would be helpful
Thanks !!!

I'm pretty sure it should be
return root = reverse(root);
(Your reverse logic is correct, but if the root is still pointing at the old root of the list, you will end up with a 1-element linked list.)

Assuming homework...
Write simple tests: list of 0 items, list of 1 items, list of 2 items, list of 10 items. Than make sure each of them work - will narrow down error and learn to write unit tests.

Are you sure you're using the returned value of reverse() to do your iteration instead of root?

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

Why can't I just do node = node.next to iterate through linked list?

I am currently doing a Cracking the Coding Interview Problem (2.4) and I am supposed to partition a linked list around a value x, such that all nodes less than x come before all nodes greater than or equal to x. However, I am really confused as to why a temporary variable "next" is needed and why is node.next nulled below it. Why can't I just do node = node.next at the end of the while loop?
I am simply creating two linked lists, before and after, and merging them together once the correct values are put into each list.
public static Node partition(Node node, int x) {
Node beforeStart = null;
Node beforeEnd = null;
Node afterStart = null;
Node afterEnd = null;
/* Partition list */
while (node != null) {
Node next = node.next;
node.next = null;
if (node.data < x) {
if (beforeStart == null) {
beforeStart = node;
beforeEnd = beforeStart;
} else {
beforeEnd.next = node;
beforeEnd = beforeEnd.next;
}
} else {
if (afterStart == null) {
afterStart = node;
afterEnd = afterStart;
} else {
afterEnd.next = node;
afterEnd = afterEnd.next;
}
}
node = next;
}
/* Merge before list and after list */
if (beforeStart == null) {
return afterStart;
}
beforeEnd.next = afterStart;
return beforeStart;
}
Why can't I just do node = node.next at the end of the while loop?
It can be done this way. After doing the partition, for each list, you need to set the last node's next pointer to NULL. This will just take two lines of code.
The example code is using next = node.next and node.next = NULL to terminate each list during the partition process, but in this case that's not needed, since the lists don't need NULL terminators until after the partition process is done.
The loop in your question removes nodes from the head of the original list, and appends them to the before list or the after list, until the original list is empty. Then it concatenates the before and after lists.
That's easy to explain and easy to understand.
It can be done without the temporary next or nulling out node.next in every iteration, but then the above description would no longer apply -- nodes would not be removed from the original list in every iteration, the before list and after list would not contain only the appropriate nodes, the operation you perform on them is not 'appending', and nodes would even appear in multiple lists for a while.
Your algorithm would suddenly be a lot more difficult to describe and understand. That is a bad thing in software development, and a bad thing in a coding interview.

Can someone help me visualize this reverse Linked List recursion?

The problem is to reverse a singly linked list, but I'm a bit stuck with the following code:
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null) return head;
ListNode temp = head.next;
head.next = null;
ListNode result = reverseList(temp);
temp.next = head;
return result;
}
What does line 6 do?
temp.next = head;
Without it, the result will only return the last element and not a reversed list.
The way I read it is that the code gets to line 5, gets result, goes through line 6, then returns the result at line 7, and keeps repeating until finish. How does line 6 actually affect the code?
I'm having a hard time visualizing this recursion. Can someone help?
A recursive function solves a problem by making use of smaller versions of the exact same problem. There are two main parts to a recursive function: the base case and the recursive case. The base case is the smallest version of the problem where we provide a solution without having to use recursion. It's where the recursion stops. The recursive case makes the assumption that the smaller versions of the problem provide correct solutions and we use those solutions to solve the larger versions.
reverseList() takes the head node of a linked list as input, reverses each node in the list, and returns the head node of the new reversed list.
Let's say you have a linked list:
a->b->c->d->e
head points to node a and temp points to node b.
On line 4, node a is disconnected from the original list resulting in two sublists, one containing only a and the other containing the other elements starting with b. Now, assuming that line 5 correctly reverses the sublist starting with b, we have:
a
e->d->c->b
head still points to a, temp still points to b, and result points to e (the head of the reversed sublist).
In order to correctly reverse our original list, we just add node a (head) to the end of the reversed sublist (temp).
Now the list is:
e->d->c->b->a
where the new head points to e.
Line 6 only make link between the nodes. recursion goes all the way to last node and make link reverse.
EDIT : Posted full code.
I wrote an alternative that you may understand better. I also set the function as static ( getters and setters not used for more straightforward explanation).
public class ListNode {
// should be private variables
int value;
ListNode next;
ListNode(int val, ListNode nodeList){
this.value = val;
this.next = nodeList;
}
public static ListNode reverseList(ListNode head) {
if( head.next.next != null)
reverseList (head.next);
head.next.next = head;
head.next = null;
return head;
}
#Override
public String toString(){
String ret = "";
if ( next != null ){
ret = next.toString();
}
ret += String.valueOf(value);
return ret;
}
}
public class Main {
public static void main(String[] args) {
ListNode n0 = new ListNode(4, null),
n1 = new ListNode(3, n0),
n2 = new ListNode(2, n1),
n3 = new ListNode(1, n2),
n4 = new ListNode(0, n3);
System.out.println(n4);
ListNode.reverseList(n4);
System.out.println(n0); // <-- n4 now is the last item, check n0 instead !
}
}
Output
43210
01234
It may be easier for you to understand it here. Drawing it the before and after always helps. Like this, but only changing the arrows insted of the position of the boxes.

given a node how can I find previous node in a singly linked list

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
}

how to reverse a list with O(1) space and O(n) time?

I am looking for a method that reverses the same instance of a given list, with O(1) additional space and O(n) time.
this is not HW nor I am looking for some library method to do the job for me, as this is only an exercise for myself, and out of pure curiousity.
any ideas how to do it with O(1) additional space and O(n) time? (and if possible without reflection as well)?
signature is public <T> void reverse(List<T> list).
(*)assume get() to the head and tail of the list is O(1), but to the middle of it is O(n).
I came up with a recursive solution, but it is O(n) space, O(n) time
public <T> void reverseAux(List<T> list,int size) {
if (size == 0) return;
T elem = list.remove(size-1);
reverseAux(list,size-1);
list.add(0,elem);
}
public <T> void reverse(List<T> list) {
reverseAux(list, list.size());
}
EDIT: I am looking for a java solution, for List<T>, only assumption on implementation is access time O(1) for head and tail, and using List<T> interface.
Just read one of the following. It is the thing you're talking about.
Please note that we're talking about singly 'linked' lists.
http://www.teamten.com/lawrence/writings/reverse_a_linked_list.html
http://www.mytechinterviews.com/reverse-a-linked-list
http://www.geekpedia.com/code48_Reverse-a-linked-list.html
http://www.codeproject.com/KB/recipes/ReverseLinkedList.aspx
Plus an extra question for you:
How would you find Nth element from the tail of a linked list assuming it is singly linked and you have only head pointer with O(1) space and O(N) time?
using ListIterators:
ListIterator<T> head = list.listIterator();
ListIterator<T> tail = list.listIterator(size);//assuming this can be done in O(1) though O(n) doesn't hurt that much and total is still O(n)
while(head.nextIndex()<tail.previousIndex()){
T tmp = head.next();
head.set(tail.previous());
tail.set(tmp);
}
You already know the length. So just use 1 temporary variable and start at index 0 and go on swapping list[0] and list[length -1], then list[1] and list[length-2], and so on. O(n) time and O(1) space for 1 temporary variable.
EDIT: Just noticed you assume O(n) for accessing the middle of the list. oh well. nevermind.
alternatively, store the next/previous pointers of the two elements you swapped to move towards the middle (assuming it's a doubly linked list). Then you get O(n) time.
The best performance you can get from comparison sorts like merge sort or quick sort is O(nlogn). You can get O(n) performance from non-comparison sorts like radix sort.
If you are reversing a linked-list, then you can reverse the list in O(n) time with using just 3 extra items. You need 3 pointers to keep track of what you're currently pointing to, what is before your current item and what is after your current item. The code is:
Node current = head;
Node next = null;
Node prev = null;
while (current != null) {
next = current.next;
current.next = prev;
prev = current;
current = next;
}
return prev;
As discussed, in the general case this is not doable, you need to assume something about the complexity of the individual operations. If you have constant-time next() and previous() for the iterators, use the solution already given. It should work for both LinkedList and ArrayList.
I thought about a solution which would work for a singly-linked list (but not for something like ArrayList), but sadly the ListIterators add method inserts the element before the cursor instead of after it, thus it is not doable with the List + ListIterator interfaces (if we can't patch the ListIterator implementation to cache the pre-insert element to allow a single previous() after add in O(1)).
Here, assuming a simple Node class with next-pointer:
/**
* reverses a singly linked list.
* #param first the fist node. This will be the new last node.
* #param last the last node. This will be the new first node.
*/
void reverseList(Node first, Node last) {
while(first != last) {
Node temp = first;
first = temp.next;
temp.next = last.next;
last.next = temp;
}
}
In index terms, this would be something like this:
public void reverseList(List<T> list) {
int index = list.size() -1;
while(n > 0) {
T element = list.remove(0);
list.add(n, element);
n--;
}
}
In ListIterator terms, this would be something like this:
public void reverseList(List<T> list) {
ListIterator<T> it = list.listIterator(list.size());
while(it.previousIndex() > 0) { // we could count ourself here, too
T element = list.remove(0);
it.add(element);
it.previous();
}
}
Of course, usual singly linked list implementations will not have a O(1) previous implementation, thus it will not work there, as said before. (And they might throw a ConcurrentModificationException, or return erronous previousIndex.)
Here is a solution in Java, with O(n) time complexity (just a single pass) and O(1) space complexity (Using just two temporary variables):
private static void reverseLinkedList() {//O(n) Time complexity, O(1) space complexity
//two temp pointers
Node next = null, previous = null;
while(head.next != null){
next = head.next;//move next to next address
head.next = previous; //previous node will be the next node for head, so that head will point reverse
previous = head; //incrementing previous to the current node
head = next; //incrementing head
}
//at this point head points to last node and previous has the remaining reversed array
head.next = previous;
System.out.println("\nReversed");
}
Full code goes like:
package com.test;
public class LinkedListReverse {
private static Node head;
public static void main(String[] args) {
for(int i = 0 ; i< 10 ; i++){
addToLinkedList(i);
}
System.out.println("Added Data");
printLinkedList();
reverseLinkedList();
printLinkedList();
}
private static void reverseLinkedList() {//O(n) Time complexity, O(1) space complexity
//two temp pointers
Node next = null, previous = null;
while(head.next != null){
next = head.next;//move next to next address
head.next = previous; //previous node will be the next node for head, so that head will point reverse
previous = head; //incrementing previous to the current node
head = next; //incrementing head
}
//at this point head points to last node and previous has the remaining reversed array
head.next = previous;
System.out.println("\nReversed");
}
/* Logic for adding and printing linked list*/
private static void printLinkedList() {
System.out.println("Printing linked list");
Node temp = head;
while(temp.next != null){
System.out.print(temp.value+" ");
temp = temp.next;
}
System.out.print(temp.value+" ");//print the value at the last node
}
private static void addToLinkedList(int value){
if(head == null){
head = new Node(value, null);
}else{
Node temp = head;
while(temp.next != null){
temp = temp.next;
}
temp.next = new Node(value, null);
}
}
}
//Linked List definition
class Node{
int value;
Node next;
public Node(int value, Node next){
this.value = value;
this.next = next;
}
}
Program's Output:
Added Data
Printing linked list
0 1 2 3 4 5 6 7 8 9
Reversed
Printing linked list
9 8 7 6 5 4 3 2 1 0
Hope it helps :)
The ListIterator interface is what you're looking for (under the reasonable assumption that the list in question fully supports it; both ArrayList and LinkedList do):
ListIterator<T> fwd = list.listIterator();
ListIterator<T> back = list.listIterator(list.size());
while (fwd.nextIndex() < back.previousIndex()) {
T tmp = fwd.next();
fwd.set(back.previous());
back.set(tmp);
}
Even on linked lists, this should be linear in time.
public LinkedList Reverse(LinkedList head)
{
if (head == null) return null; // first question
if (head.Next == null) return head; // second question
// third question
// so we grab the second element (which will be the last after we reverse it)
LinkedList secondElem = head.Next;
// bug fix - need to unlink list from the rest or you will get a cycle
head.Next = null;
// then we reverse everything from the second element on
LinkedList reverseRest = Reverse(secondElem);
// then we join the two lists
secondElem.Next = head;
return reverseRest;
}

Categories