Multiple the contents of the Nodes Linked List - java

I have a programming challenge that is to recursively multiple the data in the nodes of the list following it. For example
2 - 4 - 6 - 8
will be
384 - 192- 48 - 8
This is what I have done so far in the void product method. I keep getting a null pointer exception. What is wrong with my product method
class Node
{
private int data;
private Node next;
private Node prev;
public Node(int newData,Node newNext,Node newPrev)
{
data = newData;
next = newNext;
prev = newPrev;
}
public int getData()
{
return data;
}
public void setData(int otherData)
{
this.data = otherData;
}
public Node getNext()
{
return next;
}
public Node getPrev()
{ return prev;
}
public void setNext(Node newNext)
{
next = newNext;
}
public void setPrev(Node newPrev)
{
prev = newPrev;
}
}
class LinkedList
{
private Node head;
private Node start;
private Node end;
public LinkedList()
{
head = null;
start = null;
end = null;
}
public void insert(int data)
{
Node newNode = new Node(data,null,null);
if(start == null)
{
start = newNode;
end = start;
}
else
{
newNode.setPrev(end);
end.setNext(newNode);
end = newNode;
}
}
public void product()
{
product(head);
}
public void product(Node head)
{
Node next = head.getNext();
if(head == null)
{
return;
}
else
{
int data = head.getData() * next.getData();
head.setData(data);
product(head.getNext());
}
}
}

You are calling head.getNext() and next.getData() without checking if either of head or next is null, so the program will crash when processing the last node. Even so, you are only multiplying two consecutive items and not accumulating the product.
You can make use of the function's return value to accumulate the right answer:
public void product()
{
product(head);
}
public int product(Node head)
{
if(head == null)
{
return 1;
}
else
{
int data = head.getData() * product(head.getNext());
head.setData(data);
return data;
}
}

I didn't check the logic of your entire code, but the first thing that comes to mind is that you assign:
Node next = head.getNext();
And then you check if(head == null) but what about if(next == null)?
If it is, then you have your error right here:
next.getData()
Because head can be non-null, but its next can certainly be null.
The correct course of action would be to first check if(head == null), then assign Node next = head.getNext();, and then check if(next == null).

First, you call getNext() method on head and then you check if head is null? That is clearly wrong.
You should first check if head is null. Then you should check if next is null.
Also I don't think your recursion will compute the product correctly, since you multiply the data in your current head with what's currently in next - you could achieve that with a simple loop.
Instead you should call product(next) first and compute product later. Like this (didn't test it though)
public void product(Node head)
{
if (head == null)
return;
Node next = head.getNext();
product(next);
if (next != null)
{
int data = head.getData() * next.getData();
head.setData(data);
}
}

Related

Deleting a Node in a Doubly Linked List at a specfic index in java

I have created a doubly linked list, that appends new nodes to the doubly linked list. I am currently trying to work on deleting a node at a specific index.
This is my node class, which initializes three variables, next, previous, and it imports objects from a student class that I have. Shouldn't the for loop iterate up to the value of the index entered and then redirect the next value?
Node Class:
public class Node {
Student student;
Node next;
Node previous;
public Node(Student student) {
this.student = student;
this.next = null;
this.previous = null;
}
#Override
public String toString() {
return student.toString();
}
}
DoublyLinkedList Class:
public class DoublyLinkedList <T extends Comparable<T>> {
protected Node head;
protected Node tail;
int size=0;
public DoublyLinkedList() {
this.head = null;
this.tail = null;
}
public Node append(Student student) {
Node append = new Node(student);
if (head == null) {
head = append;
tail = append;
}
else {
append.previous = tail;
tail.next = append;
tail = tail.next;
}
size++;
return append;
}
public void delete(int location) throws IllegalArgumentException {
Node current = head;
int counter = 1;
int i;
// Exception error for cases in which there are no nodes
if (head == null || location < 0)
throw new IllegalArgumentException("Sorry but the DLL is NULL, please add nodes");
// Cases in which the person wants to delete the head at index 0
if (location == 0) {
/* If the node that is next is not null we make that the head
*/
if (head.next != null) {
head.next.previous = head;
}
}
for (i = 1; head != null && i < location; i++) {
head = head.next;
}
if (head == null)
head = head.next.previous;
}
}
I believe the cases that I made for situations where the head is null, a negative value is entered, and the head node is being deleted are correct. I believe the problem is iterating up the given parameter (index of node being deleted). I did a for loop that iterates up to the given index. What I was trying to do is once the value of head reaches the parameter entered, it would redirect the next of the Node it iterated up to. Is this logic correct and the syntax wrong or is there another logic for a case like this?
Your DoublyLinkedList class is generic. Therefore class Node should also be generic. Consequently, class Student needs to implement interface Comparable.
Since you have a doubly-linked list, method delete also needs to update tail in class DoublyLinkedList.
Since class DoublyLinkedList has member size, method delete also needs to update that member as well.
Because class DoublyLinkedList has member size, the parameter, location, of method delete is valid if it is not negative and also if it is less than size.
There are three, separate cases that method delete needs to handle:
You are deleting the first Node in DoublyLinkedList.
You also need to handle the case where there is only one Node in DoublyLinkedList.
You are deleting the last Node in DoublyLinkedList.
You are deleting a Node which is neither the first nor the last.
You also need to handle the case where you are deleting the second last Node.
You didn't post code for class Student so I just made up a class.
In the below code, I added toString method in class DoublyLinkedList simply in order to help "visualize" the list.
I also added a main method to class DoublyLinkedList to demonstrate use of method delete.
public class DoublyLinkedList<T extends Comparable<T>> {
protected Node<T> head;
protected Node<T> tail;
int size = 0;
public DoublyLinkedList() {
this.head = null;
this.tail = null;
}
public Node<T> append(T student) {
Node<T> append = new Node<>(student);
if (head == null) {
head = append;
tail = append;
}
else {
append.previous = tail;
tail.next = append;
tail = tail.next;
}
size++;
return append;
}
public void delete(int location) throws IllegalArgumentException {
// Exception error for cases in which there are no nodes
if (head == null || location < 0 || location >= size)
throw new IllegalArgumentException("Sorry but the DLL is NULL, please add nodes");
// Cases in which the person wants to delete the head at index 0
if (location == 0) {
head = head.next;
if (head != null) {
head.previous = null;
}
if (size == 2) {
tail = head;
}
}
else if (location == size - 1) {
tail = tail.previous;
tail.next = null;
}
else {
Node<T> current = head;
for (int i = 1; i < location; i++) {
current = current.next;
}
current.next = current.next.next;
if (current.next == null) {
tail = current;
}
else {
current.next.previous = current;
}
}
size--;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(String.format("[%d]:", size));
Node<T> current = head;
while (current != null) {
sb.append(current);
sb.append('\u2192');
current = current.next;
}
return sb.toString();
}
public static void main(String[] args) {
DoublyLinkedList<Student> dll = new DoublyLinkedList<>();
System.out.println(dll);
dll.append(new Student());
System.out.println(dll);
dll.append(new Student());
System.out.println(dll);
dll.append(new Student());
System.out.println(dll);
dll.append(new Student());
System.out.println(dll);
dll.delete(1);
System.out.println(dll);
}
}
class Student implements Comparable<Student> {
private static int counter;
private int id;
public Student() {
id = ++counter;
}
#Override
public int compareTo(Student o) {
return id - o.id;
}
public boolean equals(Object obj) {
boolean equal = this == obj;
if (!equal) {
if (obj instanceof Student) {
Student other = (Student) obj;
equal = id == other.id;
}
}
return equal;
}
public int hashCode() {
return id;
}
public String toString() {
return String.format("%d", id);
}
}
class Node<T> {
T student;
Node<T> next;
Node<T> previous;
public Node(T student) {
this.student = student;
this.next = null;
this.previous = null;
}
#Override
public String toString() {
return student.toString();
}
}
This seems to be homework, so I won't give a full code, but pointers to where mistakes are. If this isn't the case feel free to comment and I'll remove this. This should be a comment, but this is too long to fit in the comment section.
There are four things that seem off in the delete method:
When iterating over the array to find the node to delete, the head is modified.
for (i = 1; head != null && i < location; i++) {
head = head.next;
}
This will permanently modify the head of the doubled linked list, meaning that the nodes before the new head are lost.
You should use a variable to iterate (I believe current was supposed to be that ?)
When you delete the head
It's correct that there is additional work to do when the location to delete is the head, but head.next.previous = head; does nothing : head is already the previous node of head.next.
When you delete the tail
There is additional work to do when you delete the head, but also when you delete the tail.
You never actually remove anything
Other than the lost nodes when iteration, you never remove any node form the list.
I suggest you start with simple case and see what your current implementation does, then try to correct it. You can also do it pen and paper by drawing the double linked list, this could help you build an intuition on what steps should be done.

Writing a method to sort a singly linkedlist in ascending order (java)

the method 'insertAscending' only gives me the first number even after i enter new ones. can anyone help with what i'm doing wrong? Thanks.
public class LinkedList13 {
// Private inner class Node
private class Node{
int data;
Node link;
public Node(){
data = Integer.MIN_VALUE;
link = null;
}
public Node(int x, Node p){
data = x;
link = p;
}
}
// End of Node class
public Node head;
public LinkedList13(){
head = null;
}
public void insertAscending(int data){
Node node = new Node();
node.data = data;
if (head == null)
head = node;
Node p = head;
while (p.link != null)
{
if (p.link.data > data)
{ node.link = p.link;
p.link = node;
break;
}
p= p.link;
}
}
}
Hint: is (p.link != null) ever true?
First of all, you should return after setting the head of the list (when the first element is added).
Second of all, you should handle the case where the newly inserted node is the smallest in the list (and therefore should come first). Your loop never compares the added node to the head of the list.
Finally, if the added element wasn't inserted in the while loop, it should be inserted after the while loop.
public void insertAscending(int data)
{
Node node = new Node();
node.data = data;
if (head == null) {
head = node;
return;
} else if (node.data < head.data) {
node.link = head;
head = node;
return;
}
Node p = head;
boolean added=false;
while (p.link != null)
{
if (p.link.data > data)
{
node.link = p.link;
p.link = node;
added = true;
break;
}
p = p.link;
}
if (!added)
p.link = node;
}
Check out your if condition if(p.link.data > data) the only way a node gets into the list is when that is true. This means, that, if the value of data being inserted it greater than (or equal to) everything that's been inserted so far, it will be discarded.
An easy way to fix this is change break to return and add p.link=node at the end (after the loop).

Removing values from a custom LinkedList class

This custom class mimics the functionality of Java's LinkedList Class except it only takes integers and obviously lacks most of the functionality. For this one method, removeAll(), I am to go through each node for the list and remove all nodes with that value. My problem is that when the first node in the list contains the value to be removed, it then ignores all subsequent nodes that also contain that value. What seems to be the problem? Am I removing the front node the wrong way? For example, [1]->[1]->[1] should return an empty list, but it leaves the front node and I get [1]
edit: it seems to fail to remove the second node instead of the first.
This is the class (Stores ListNodes as a list):
public class LinkedIntList {
private ListNode front; // first value in the list
// post: constructs an empty list
public LinkedIntList() {
front = null;
}
// post: removes all occurrences of a particular value
public void removeAll(int value) {
ListNode current = front; // primes loop
if (current == null) { // If empty list
return;
}
if (front.data == value) { // If match on first elem
front = current.next;
current = current.next;
}
while (current.next != null) { // If next node exists
if (current.next.data == value) { // If match at next value
current.next = current.next.next;
} else { // If not a match
current = current.next; // increment to next
}
}
}
// post: appends the given value to the end of the list
public void add(int value) {
if (front == null) {
front = new ListNode(value);
} else {
ListNode current = front;
while (current.next != null) {
current = current.next;
}
current.next = new ListNode(value);
}
}
// Sets a particular index w/ a given value
public void set(int index, int value) {
ListNode current = front;
for (int i = 0; i < index; i++) {
current = current.next;
}
current.data = value;
}
}
Here is the ListNode class (responsible for a single "node"):
//ListNode is a class for storing a single node of a linked
//list. This node class is for a list of integer values.
public class ListNode {
public int data; // data stored in this node
public ListNode next; // link to next node in the list
// post: constructs a node with data 0 and null link
public ListNode() {
this(0, null);
}
// post: constructs a node with given data and null link
public ListNode(int data) {
this(data, null);
}
// post: constructs a node with given data and given link
public ListNode(int data, ListNode next) {
this.data = data;
this.next = next;
}
}
The [1] element that actually stays in the list is the second element which becomes the front element in your code:
if (front.data == value) { // If match on first elem
front = current.next;
current = current.next;
}
After that you just iterate over the list and remove the matching elements.
Replacing the problematic code with this should do the work:
while (front.data == value) { // If match on first elem
front = front.next;
if (front == null) {
return;
}
}
One of the simplest and cleanest way to remove element from a custom Linked list is as follows.
import java.util.concurrent.atomic.AtomicInteger;
public class LinkedList<T> {
class Node<T> {
private T data;
private Node<T> next;
Node(T data) {
this.data = data;
this.next = null;
}
}
private Node<T> head;
private Node<T> tail;
private AtomicInteger size = new AtomicInteger();
public void add(T data) {
Node<T> n = new Node<T>(data);
if (head == null) {
head = n;
tail = n;
size.getAndIncrement();
} else {
tail.next = n;
tail = n;
size.getAndIncrement();
}
}
public int size() {
return size.get();
}
public void displayElement() {
while (head.next != null) {
System.out.println(head.data);
head = head.next;
}
System.out.println(head.data);
}
public void remove(int position) throws IndexOutOfBoundsException {
if (position > size.get()) {
throw new IndexOutOfBoundsException("current size is:" + size.get());
}
Node<T> temp = head;
for (int i = 0; i < position; i++) {
temp = temp.next;
}
head = null;
head = temp;
size.getAndDecrement();
}
}

Inspect a Queue to print all elements

I am currently revising for my programming exam and I have came across a question from a past paper that has me rather confused.
I have two classes, Queue and Node, shown below.
The question states that I have to extend the behaviour of the Queue class by adding the necessary code to the inspectQueue method that prints to the console all the data stored within the queue.
The only solution I can think of, and it is very weak, is to have a simple ArrayList and every time an element is enqueued/dequeued then add/remove the node to/from the list.
Is there a better solution that I am glossing over? I'd really appreciate some guidance.
I've commented the code where I have implemented my "solution" the rest of the code is how it appears in the exam paper.
Thanks for your time.
Queue.java
public class Queue {
protected Node head;
protected Node last;
//added by me
private ArrayList<Node> nodes = new ArrayList<Node>();
//end my add
public boolean isEmpty() {
return (this.head == null);
}
public void enqueue(Object d) {
Node n = new Node();
n.setData(d);
nodes.add(n); //added by me
if (this.isEmpty()) {
head = n;
last = n;
}
else {
last.setNext(n);
last = n;
}
}
public Object dequeue() {
if(this.isEmpty()) {
this.last = null;
return null;
}
else {
Node h = this.head;
nodes.remove(h); //added by me
head = h.getNext();
return h.getData();
}
}
public Object peek() {
if(this.isEmpty()) {
return null;
}
else {
Node t = this.head;
return t.getData();
}
}
public void clearQueue() {
this.head = null;
this.last = null;
}
public void inspectQueue() {
//added by me (all below)
System.out.println("Inspecting Queue: (contains " + nodes.size() + " nodes)");
for(Node n : nodes) {
System.out.println(n.getData());
}
}
}
Node.java
public class Node {
protected Object data;
protected Node next;
public void setNext(Node e) {
this.next = e;
}
public Node getNext() {
return this.next;
}
public void setData(Object d) {
this.data = d;
}
public Object getData() {
return this.data;
}
}
Your nodes form a linked list, so just do
public void inspectQueue() {
Node n = head;
while (n != null) {
System.out.println(n.getData());
n = n.getNext();
}
}
This is a very basic data structure, called a LinkedList. In the your code for the Node class you can see the following:
protected Node next;
This means that every Node also holds a reference to the next Node in the list. If this Node is null, there are no more elements in the list. Knowing this, you can loop somewhat like this:
Node currentNode = this.head;
while(currentNode != null) {
System.out.println(currentNode.getData().toString());
currentNode = currentNode.getNext();
}
This eliminates the need for an ArrayList to store your references.
The LinkedList is a VERY frequently used data structure and very important to understand. If you have any questions, just go ahead and ask!
If you also want to have the size, keep a counter along, increment it each time you call getNext(), and print the size after the for loop.
You don't need the array, you have that information stored within the Node next property:
public void inspectQueue() {
Node current = head;
while(current != null) {
System.out.println(n.getData());
current = current.getNext();
}
}
That data structure is called linked list.
The simpler solution is to start with queue.head and traverse the linked list of nodes using node.next, printing the data as you go along.

Reversing a linked list in Java, recursively

I have been working on a Java project for a class for a while now. It is an implementation of a linked list (here called AddressList, containing simple nodes called ListNode). The catch is that everything would have to be done with recursive algorithms. I was able to do everything fine sans one method: public AddressList reverse()
ListNode:
public class ListNode{
public String data;
public ListNode next;
}
Right now my reverse function just calls a helper function that takes an argument to allow recursion.
public AddressList reverse(){
return new AddressList(this.reverse(this.head));
}
With my helper function having the signature of private ListNode reverse(ListNode current).
At the moment, I have it working iteratively using a stack, but this is not what the specification requires. I had found an algorithm in C that recursively reversed and converted it to Java code by hand, and it worked, but I had no understanding of it.
Edit: Nevermind, I figured it out in the meantime.
private AddressList reverse(ListNode current, AddressList reversedList){
if(current == null)
return reversedList;
reversedList.addToFront(current.getData());
return this.reverse(current.getNext(), reversedList);
}
While I'm here, does anyone see any problems with this route?
There's code in one reply that spells it out, but you might find it easier to start from the bottom up, by asking and answering tiny questions (this is the approach in The Little Lisper):
What is the reverse of null (the empty list)? null.
What is the reverse of a one element list? the element.
What is the reverse of an n element list? the reverse of the rest of the list followed by the first element.
public ListNode Reverse(ListNode list)
{
if (list == null) return null; // first question
if (list.next == null) return list; // second question
// third question - in Lisp this is easy, but we don't have cons
// so we grab the second element (which will be the last after we reverse it)
ListNode secondElem = list.next;
// bug fix - need to unlink list from the rest or you will get a cycle
list.next = null;
// then we reverse everything from the second element on
ListNode reverseRest = Reverse(secondElem);
// then we join the two lists
secondElem.next = list;
return reverseRest;
}
I was asked this question at an interview and was annoyed that I fumbled with it since I was a little nervous.
This should reverse a singly linked list, called with reverse(head,NULL);
so if this were your list:
1->2->3->4->5->null
it would become:
5->4->3->2->1->null
//Takes as parameters a node in a linked list, and p, the previous node in that list
//returns the head of the new list
Node reverse(Node n,Node p){
if(n==null) return null;
if(n.next==null){ //if this is the end of the list, then this is the new head
n.next=p;
return n;
}
Node r=reverse(n.next,n); //call reverse for the next node,
//using yourself as the previous node
n.next=p; //Set your next node to be the previous node
return r; //Return the head of the new list
}
edit: ive done like 6 edits on this, showing that it's still a little tricky for me lol
I got half way through (till null, and one node as suggested by plinth), but lost track after making recursive call. However, after reading the post by plinth, here is what I came up with:
Node reverse(Node head) {
// if head is null or only one node, it's reverse of itself.
if ( (head==null) || (head.next == null) ) return head;
// reverse the sub-list leaving the head node.
Node reverse = reverse(head.next);
// head.next still points to the last element of reversed sub-list.
// so move the head to end.
head.next.next = head;
// point last node to nil, (get rid of cycles)
head.next = null;
return reverse;
}
Here's yet another recursive solution. It has less code within the recursive function than some of the others, so it might be a little faster. This is C# but I believe Java would be very similar.
class Node<T>
{
Node<T> next;
public T data;
}
class LinkedList<T>
{
Node<T> head = null;
public void Reverse()
{
if (head != null)
head = RecursiveReverse(null, head);
}
private Node<T> RecursiveReverse(Node<T> prev, Node<T> curr)
{
Node<T> next = curr.next;
curr.next = prev;
return (next == null) ? curr : RecursiveReverse(curr, next);
}
}
The algo will need to work on the following model,
keep track of the head
Recurse till end of linklist
Reverse linkage
Structure:
Head
|
1-->2-->3-->4-->N-->null
null-->1-->2-->3-->4-->N<--null
null-->1-->2-->3-->4<--N<--null
null-->1-->2-->3<--4<--N<--null
null-->1-->2<--3<--4<--N<--null
null-->1<--2<--3<--4<--N<--null
null<--1<--2<--3<--4<--N
|
Head
Code:
public ListNode reverse(ListNode toBeNextNode, ListNode currentNode)
{
ListNode currentHead = currentNode; // keep track of the head
if ((currentNode==null ||currentNode.next==null )&& toBeNextNode ==null)return currentHead; // ignore for size 0 & 1
if (currentNode.next!=null)currentHead = reverse(currentNode, currentNode.next); // travarse till end recursively
currentNode.next = toBeNextNode; // reverse link
return currentHead;
}
Output:
head-->12345
head-->54321
I think this is more cleaner solution, which resembles LISP
// Example:
// reverse0(1->2->3, null) =>
// reverse0(2->3, 1) =>
// reverse0(3, 2->1) => reverse0(null, 3->2->1)
// once the first argument is null, return the second arg
// which is nothing but the reveresed list.
Link reverse0(Link f, Link n) {
if (f != null) {
Link t = new Link(f.data1, f.data2);
t.nextLink = n;
f = f.nextLink; // assuming first had n elements before,
// now it has (n-1) elements
reverse0(f, t);
}
return n;
}
I know this is an old post, but most of the answers are not tail recursive i.e. they do some operations after returning from the recursive call, and hence not the most efficient.
Here is a tail recursive version:
public Node reverse(Node previous, Node current) {
if(previous == null)
return null;
if(previous.equals(head))
previous.setNext(null);
if(current == null) { // end of list
head = previous;
return head;
} else {
Node temp = current.getNext();
current.setNext(previous);
reverse(current, temp);
}
return null; //should never reach here.
}
Call with:
Node newHead = reverse(head, head.getNext());
void reverse(node1,node2){
if(node1.next!=null)
reverse(node1.next,node1);
node1.next=node2;
}
call this method as reverse(start,null);
public Node reverseListRecursive(Node curr)
{
if(curr == null){//Base case
return head;
}
else{
(reverseListRecursive(curr.next)).next = (curr);
}
return curr;
}
public void reverse() {
head = reverseNodes(null, head);
}
private Node reverseNodes(Node prevNode, Node currentNode) {
if (currentNode == null)
return prevNode;
Node nextNode = currentNode.next;
currentNode.next = prevNode;
return reverseNodes(currentNode, nextNode);
}
Reverse by recursive algo.
public ListNode reverse(ListNode head) {
if (head == null || head.next == null) return head;
ListNode rHead = reverse(head.next);
rHead.next = head;
head = null;
return rHead;
}
By iterative
public ListNode reverse(ListNode head) {
if (head == null || head.next == null) return head;
ListNode prev = null;
ListNode cur = head
ListNode next = head.next;
while (next != null) {
cur.next = prev;
prev = cur;
cur = next;
next = next.next;
}
return cur;
}
public static ListNode recRev(ListNode curr){
if(curr.next == null){
return curr;
}
ListNode head = recRev(curr.next);
curr.next.next = curr;
curr.next = null;
// propogate the head value
return head;
}
This solution demonstrates that no arguments are required.
/**
* Reverse the list
* #return reference to the new list head
*/
public LinkNode reverse() {
if (next == null) {
return this; // Return the old tail of the list as the new head
}
LinkNode oldTail = next.reverse(); // Recurse to find the old tail
next.next = this; // The old next node now points back to this node
next = null; // Make sure old head has no next
return oldTail; // Return the old tail all the way back to the top
}
Here is the supporting code, to demonstrate that this works:
public class LinkNode {
private char name;
private LinkNode next;
/**
* Return a linked list of nodes, whose names are characters from the given string
* #param str node names
*/
public LinkNode(String str) {
if ((str == null) || (str.length() == 0)) {
throw new IllegalArgumentException("LinkNode constructor arg: " + str);
}
name = str.charAt(0);
if (str.length() > 1) {
next = new LinkNode(str.substring(1));
}
}
public String toString() {
return name + ((next == null) ? "" : next.toString());
}
public static void main(String[] args) {
LinkNode head = new LinkNode("abc");
System.out.println(head);
System.out.println(head.reverse());
}
}
Here is a simple iterative approach:
public static Node reverse(Node root) {
if (root == null || root.next == null) {
return root;
}
Node curr, prev, next;
curr = root; prev = next = null;
while (curr != null) {
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
And here is a recursive approach:
public static Node reverseR(Node node) {
if (node == null || node.next == null) {
return node;
}
Node next = node.next;
node.next = null;
Node remaining = reverseR(next);
next.next = node;
return remaining;
}
As Java is always pass-by-value, to recursively reverse a linked list in Java, make sure to return the "new head"(the head node after reversion) at the end of the recursion.
static ListNode reverseR(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode first = head;
ListNode rest = head.next;
// reverse the rest of the list recursively
head = reverseR(rest);
// fix the first node after recursion
first.next.next = first;
first.next = null;
return head;
}
PointZeroTwo has got elegant answer & the same in Java ...
public void reverseList(){
if(head!=null){
head = reverseListNodes(null , head);
}
}
private Node reverseListNodes(Node parent , Node child ){
Node next = child.next;
child.next = parent;
return (next==null)?child:reverseListNodes(child, next);
}
public class Singlelinkedlist {
public static void main(String[] args) {
Elem list = new Elem();
Reverse(list); //list is populate some where or some how
}
//this is the part you should be concerned with the function/Method has only 3 lines
public static void Reverse(Elem e){
if (e!=null)
if(e.next !=null )
Reverse(e.next);
//System.out.println(e.data);
}
}
class Elem {
public Elem next; // Link to next element in the list.
public String data; // Reference to the data.
}
public Node reverseRec(Node prev, Node curr) {
if (curr == null) return null;
if (curr.next == null) {
curr.next = prev;
return curr;
} else {
Node temp = curr.next;
curr.next = prev;
return reverseRec(curr, temp);
}
}
call using: head = reverseRec(null, head);
What other guys done , in other post is a game of content, what i did is a game of linkedlist, it reverse the LinkedList's member not reverse of a Value of members.
Public LinkedList reverse(LinkedList List)
{
if(List == null)
return null;
if(List.next() == null)
return List;
LinkedList temp = this.reverse( List.next() );
return temp.setNext( List );
}
package com.mypackage;
class list{
node first;
node last;
list(){
first=null;
last=null;
}
/*returns true if first is null*/
public boolean isEmpty(){
return first==null;
}
/*Method for insertion*/
public void insert(int value){
if(isEmpty()){
first=last=new node(value);
last.next=null;
}
else{
node temp=new node(value);
last.next=temp;
last=temp;
last.next=null;
}
}
/*simple traversal from beginning*/
public void traverse(){
node t=first;
while(!isEmpty() && t!=null){
t.printval();
t= t.next;
}
}
/*static method for creating a reversed linked list*/
public static void reverse(node n,list l1){
if(n.next!=null)
reverse(n.next,l1);/*will traverse to the very end*/
l1.insert(n.value);/*every stack frame will do insertion now*/
}
/*private inner class node*/
private class node{
int value;
node next;
node(int value){
this.value=value;
}
void printval(){
System.out.print(value+" ");
}
}
}
The solution is:
package basic;
import custom.ds.nodes.Node;
public class RevLinkedList {
private static Node<Integer> first = null;
public static void main(String[] args) {
Node<Integer> f = new Node<Integer>();
Node<Integer> s = new Node<Integer>();
Node<Integer> t = new Node<Integer>();
Node<Integer> fo = new Node<Integer>();
f.setNext(s);
s.setNext(t);
t.setNext(fo);
fo.setNext(null);
f.setItem(1);
s.setItem(2);
t.setItem(3);
fo.setItem(4);
Node<Integer> curr = f;
display(curr);
revLL(null, f);
display(first);
}
public static void display(Node<Integer> curr) {
while (curr.getNext() != null) {
System.out.println(curr.getItem());
System.out.println(curr.getNext());
curr = curr.getNext();
}
}
public static void revLL(Node<Integer> pn, Node<Integer> cn) {
while (cn.getNext() != null) {
revLL(cn, cn.getNext());
break;
}
if (cn.getNext() == null) {
first = cn;
}
cn.setNext(pn);
}
}
static void reverseList(){
if(head!=null||head.next!=null){
ListNode tail=head;//head points to tail
ListNode Second=head.next;
ListNode Third=Second.next;
tail.next=null;//tail previous head is poiniting null
Second.next=tail;
ListNode current=Third;
ListNode prev=Second;
if(Third.next!=null){
while(current!=null){
ListNode next=current.next;
current.next=prev;
prev=current;
current=next;
}
}
head=prev;//new head
}
}
class ListNode{
public int data;
public ListNode next;
public int getData() {
return data;
}
public ListNode(int data) {
super();
this.data = data;
this.next=null;
}
public ListNode(int data, ListNode next) {
super();
this.data = data;
this.next = next;
}
public void setData(int data) {
this.data = data;
}
public ListNode getNext() {
return next;
}
public void setNext(ListNode next) {
this.next = next;
}
}
private Node ReverseList(Node current, Node previous)
{
if (current == null) return null;
Node originalNext = current.next;
current.next = previous;
if (originalNext == null) return current;
return ReverseList(originalNext, current);
}
//this function reverses the linked list
public Node reverseList(Node p) {
if(head == null){
return null;
}
//make the last node as head
if(p.next == null){
head.next = null;
head = p;
return p;
}
//traverse to the last node, then reverse the pointers by assigning the 2nd last node to last node and so on..
return reverseList(p.next).next = p;
}
//Recursive solution
class SLL
{
int data;
SLL next;
}
SLL reverse(SLL head)
{
//base case - 0 or 1 elements
if(head == null || head.next == null) return head;
SLL temp = reverse(head.next);
head.next.next = head;
head.next = null;
return temp;
}
Inspired by an article discussing immutable implementations of recursive data structures I put an alternate solution together using Swift.
The leading answer documents solution by highlighting the following topics:
What is the reverse of nil (the empty list)?
Does not matter here, because we have nil protection in Swift.
What is the reverse of a one element list?
The element itself
What is the reverse of an n element list?
The reverse of the second element on followed by the first element.
I have called these out where applicable in the solution below.
/**
Node is a class that stores an arbitrary value of generic type T
and a pointer to another Node of the same time. This is a recursive
data structure representative of a member of a unidirectional linked
list.
*/
public class Node<T> {
public let value: T
public let next: Node<T>?
public init(value: T, next: Node<T>?) {
self.value = value
self.next = next
}
public func reversedList() -> Node<T> {
if let next = self.next {
// 3. The reverse of the second element on followed by the first element.
return next.reversedList() + value
} else {
// 2. Reverse of a one element list is itself
return self
}
}
}
/**
#return Returns a newly created Node consisting of the lhs list appended with rhs value.
*/
public func +<T>(lhs: Node<T>, rhs: T) -> Node<T> {
let tail: Node<T>?
if let next = lhs.next {
// The new tail is created recursively, as long as there is a next node.
tail = next + rhs
} else {
// If there is not a next node, create a new tail node to append
tail = Node<T>(value: rhs, next: nil)
}
// Return a newly created Node consisting of the lhs list appended with rhs value.
return Node<T>(value: lhs.value, next: tail)
}
Reversing the linked list using recursion. The idea is adjusting the links by reversing the links.
public ListNode reverseR(ListNode p) {
//Base condition, Once you reach the last node,return p
if (p == null || p.next == null) {
return p;
}
//Go on making the recursive call till reach the last node,now head points to the last node
ListNode head = reverseR(p.next); //Head points to the last node
//Here, p points to the last but one node(previous node), q points to the last node. Then next next step is to adjust the links
ListNode q = p.next;
//Last node link points to the P (last but one node)
q.next = p;
//Set the last but node (previous node) next to null
p.next = null;
return head; //Head points to the last node
}
public void reverseLinkedList(Node node){
if(node==null){
return;
}
reverseLinkedList(node.next);
Node temp = node.next;
node.next=node.prev;
node.prev=temp;
return;
}
public void reverse(){
if(isEmpty()){
return;
}
Node<T> revHead = new Node<T>();
this.reverse(head.next, revHead);
this.head = revHead;
}
private Node<T> reverse(Node<T> node, Node<T> revHead){
if(node.next == null){
revHead.next = node;
return node;
}
Node<T> reverse = this.reverse(node.next, revHead);
reverse.next = node;
node.next = null;
return node;
}
Here is a reference if someone is looking for Scala implementation:
scala> import scala.collection.mutable.LinkedList
import scala.collection.mutable.LinkedList
scala> def reverseLinkedList[A](ll: LinkedList[A]): LinkedList[A] =
ll.foldLeft(LinkedList.empty[A])((accumulator, nextElement) => nextElement +: accumulator)
reverseLinkedList: [A](ll: scala.collection.mutable.LinkedList[A])scala.collection.mutable.LinkedList[A]
scala> reverseLinkedList(LinkedList("a", "b", "c"))
res0: scala.collection.mutable.LinkedList[java.lang.String] = LinkedList(c, b, a)
scala> reverseLinkedList(LinkedList("1", "2", "3"))
res1: scala.collection.mutable.LinkedList[java.lang.String] = LinkedList(3, 2, 1)

Categories

Resources