Reverse a linked list recursively in Java [duplicate] - java

This question already has answers here:
Reversing a linked list in Java, recursively
(33 answers)
Closed 6 years ago.
I am trying to achieve a reversed link list. The new fresh list must be created recursively.
I am creating the first node in the reversed list and I am trying to create a sublist Next which has the next element as next.next and finally to assign this sublist as next to the node. The issue is that the next node remains NIL although I recreated it in the for loop.
Edit:
The function must not change (add arguments) because some tests are running upon it.
class Node {
private Object item;
private Node next,current;
public Node(Object o, Node n) {
this.item = o;
this.next = n;
}
public Node(Node n) {
}
public static final Node NIL = new Node(Node.NIL, Node.NIL);
public Object getItem() {
return this.item;
}
public Node getNext() {
return this.next;
}
public void setItem(Object o) {
this.item = o;
}
public void setNext(Node n) {
this.next = n;
}
// this method returns the item with index number i
public Object nthItem(int i) {
Node p = this;
while (p!=null){
for (int k=1;k<=i;k++){
p=p.next;
}
return p.item;
}
return null;
}
// this method returns the the next item of the node
public Node nthNext(int i) {
Node p = this;
while (p!=null){
for (int k=1;k<=i;k++){
p=p.next;
}
return p.getNext();
}
return null;
}
public Node nthNode(int i) {
Node p = this;
while (p!=null){
for (int k=1;k<=i;k++){
p=p.next;
}
return p;
}
return NIL;
}
public int length(){
if (this == NIL) return 0;
else return 1 + next.length();
}
public Node remove(Object o){
Node p = this;
if (p == NIL) return NIL;
else if(p.item == o) {
p = p.next;
return p.remove(o);
}
else return new Node(p.item, p.next.remove(o));
}
public Node reverse() {
int i = this.length()-1;
if(this == NIL) return NIL;
Node node = new Node(Node.NIL, Node.NIL);
Node next = NIL;
//create the first node in the reversed list
if(i >= 1) node = new Node(nthItem(i), next);
else node = new Node(nthItem(i), Node.NIL);
//iterate through the original list and create a next node
if (i>0) {
for (int k=i; k>=0; k--){
if (k<=0) {
next = NIL;
}
else {
next = new Node(nthItem(k-1),next);
}
}
}
//debugging in console
System.out.println("final node = " + next.item+" ");
return node;
}
}
class Test{
public static void main(String[] string){
Node n = new Node(1, Node.NIL);
Node nn = new Node(2, n);
Node r = nn.reverse();
System.out.println("\t item " + r.getItem()+ " " + r.getNext().getItem() + " length " + r.length());
}
}

This is a question designed to test whether you understand the implicit stack.
Each time you make a recursive call, you add a stack frame, so consider the stack as if you were performing the routine iteratively.
To reverse the list:
Stack all elements in order
Make a new list by popping each element.
Now convert this to a recursive call
//in [1,2,3,null]
Node reverse(Node n){
//base case
if(n == null)
{
return null;
}
// returns [null,3,2,1]
Node next = reverse(n.getNext());
next.setNext(n);// set the next nodes next to its previous(n on unwinding)
return n;
}
Note that the reverse method here doesn't return the new head, to get the head of the reversed list do the following, maybe making a the above a helper instead.
Node oldHead = n;
Node newHead = tail(n);
oldHead.reverse();

Related

How to insert a node in specific index [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
First of all pardon me if the way I'm asking is wrong, I'm new at programming and still need a lot of learning, here is my code
This is my Node class
public class Node
{
int value;
Node link;
void setValue(int a){
value = a;
}
int getValue(){
return value;
}
void setNode(Node i){
link = i;
}
Node getNode(){
return link;
}
}
And this one my NodeContainer class
public class NodeContainer
{
Node tail;
Node head;
void setHead(int i){
Node a = new Node();
a.setValue(i);
head = a;
tail = head;
}
Node getHead(){
return head;
}
void addNode(int i){
Node a = new Node();
a.setValue(i);
tail.setNode(a);
tail = a;
}
void addNode(int i,int index){
Node a = new Node();
a.setValue(i);
int c = 1;
Node temp = head;
Node first = head;
while(head!=null){
head = head.getNode();
if(c==index-1){
a.setNode(head.getNode());
temp = head;
temp.setNode(a);
}
c++;
}
head = first;
head.setNode(temp);
}
int count(){
int c = 1;
boolean have = true;
if(head!=null){
while(head.getNode()!=null){
c++;
head = head.getNode();
}
return c;
}
else{
have = false;
return 0;}
}
}
i just cant think a way to insert a node in spesific index, i tried it on addNode method have tried so many ways i can think of but it cant work, thanks in advance
Comments:
You do not need to keep track of the tail (necessarily) I see you are new to linked lists, so perhaps try to master the basics before adding extra features.
Also, try adding some white space in your code, it makes it easier to read.
I heavily commented the section that covers inserting at a specified index. put all these files in the same folder, the compile it. You should get the output that follows:
Output:
0 1 2 3 4 5 6 7 8 9
inserting -1 at position 5
0 1 2 3 4 -1 5 6 7 8 9
Main class:
class test {
public static void main(String[] args) {
NodeContainer linkedList = new NodeContainer();
for (int i = 0; i < 10; i++) {
linkedList.addNode(i);
}
display(linkedList.head);
// NOTE - indexes start at 0, not 1
System.out.println("inserting -1 at position 5");
linkedList.addNode(-1, 5);
display(linkedList.head);
}
public static void display(Node node) {
while (node != null) {
System.out.print(node.value + " ");
node = node.link;
}
System.out.println();
}
}
Node Container class:
public class NodeContainer {
public Node head;
public int size;
public NodeContainer() {
size = 0;
head = null;
}
public void addNode(int i) {
Node node = new Node(i);
if (head == null) {
head = node;
} else {
Node temp;
temp = head;
while (temp.link != null) {
temp = temp.link;
}
temp.link = node;
}
size++;
}
public void addNode(int i, int index) {
Node node;
Node temp;
int count;
// If we want to insert
// into the front of the list
if (index == 0) {
// User a constructor instead of
// making a new node every time,
// then typing set value
node = new Node(i);
node.link = head;
head = node;
// If the index is within the linkedlist
} else if (index > 0 && index < size) {
count = 0;
temp = head;
// Keep looking until the index prior to
// the one we want to insert at
while(temp.link != null && count < size) {
// Once we find it, break out the loop
if (count == index-1) {
break;
}
// Keep traversing the list
temp = temp.link;
// increment counter
count++;
}
// Instantiate the node
node = new Node(i);
// Point this node's link to
// the n-1th node's link
node.link = temp.link;
// Set n-1th node's next to this
// node (effectively putting it
// in position n)
temp.link = node;
// Otherwise don't do anything
} else {
;
}
}
}
Node class:
public class Node {
public int value;
public Node link;
// User a constructor
public Node(int i) {
value = i;
link = null;
}
public void setValue(int a) {
value = a;
}
public int getValue() {
return value;
}
public void setNode(Node i) {
link = i;
}
public Node getNode() {
return link;
}
}
I have updated your original code snippet to be like this :
public class Node
{
int value;
Node next;
void setValue(int value){
this.value = value;
}
int getValue(){
return this.value;
}
void setNext(Node next){
this.next = next;
}
Node getNext(){
return this.next;
}
}
public class NodeContainer {
Node tail;
Node head;
void setHead(int i) {
Node a = newNode(i);
head = a;
tail = a;
}
private Node newNode(int value) {
Node node = new Node();
node.setValue(i);
return node;
}
void addNode(int i) {
Node a = newNode(i);
Node tmp = this.head;
while(tmp.getNext() != null){
tmp = tmp.getNext();
}
tmp.setNext(a);
tail = a;
}
void addNode(int value, int index) {
//TODO : add check on head
Node a = newNode(value);
Node tmp = this.head;
int i = 0;
while(tmp.getNext()!=null && i < index) {
tmp = tmp.getNext();
i++;
}
//TODO : add check on tmp
Node next = tmp.getNext();
tmp.setNext(a);
a.setNext(next);
}
int count() {
//...
}
}

Reversing a singly linked list in java

I made a singly linked list from scratch in java. The code is as follows:
public class SingleLinkedList<Item>
{
private Node head;
private int size;
private class Node
{
Item data;
Node next;
public Node(Item data)
{
this.data = data;
this.next = null;
}
public Node(Item data, Node next)
{
this.data = data;
this.next = next;
}
//Getters and setters
public Item getData()
{
return data;
}
public void setData(Item data)
{
this.data = data;
}
public Node getNext()
{
return next;
}
public void setNext(Node next)
{
this.next = next;
}
}
public SingleLinkedList()
{
head = new Node(null);
size = 0;
}
public void add(Item data)
{
Node temp = new Node(data);
Node current = head;
while(current.getNext() != null)
{
current = current.getNext();
}
current.setNext(temp);
size++;
}
public void add(Item data, int index)
{
Node temp = new Node(data);
Node current = head;
for(int i=0; i<index && current.getNext() != null; i++)
{
current = current.getNext();
}
temp.setNext(current.getNext());
current.setNext(temp);
size++;
}
public Item get(int index)
{
if(index <= 0)
{
return null;
}
Node current = head;
for(int i=1; i<index; i++)
{
if(current.getNext() == null)
{
return null;
}
current = current.getNext();
}
return current.getData();
}
public boolean remove(int index)
{
if(index < 1 || index > size())
{
return false;
}
Node current = head;
for(int i=1; i<index; i++)
{
if(current.getNext() == null)
{
return false;
}
current = current.getNext();
}
current.setNext(current.getNext().getNext());
size--;
return true;
}
public String toString()
{
Node current = head.getNext();
String output = "";
while(current != null)
{
output+=current.getData().toString()+" ";
current = current.getNext();
}
return output;
}
public int size()
{
return size;
}
public void reverse()
{
Node current = head;
Node prevNode = null;
Node nextNode;
while(current!=null)
{
nextNode = current.getNext();
current.setNext(prevNode);
prevNode = current;
current = nextNode;
System.out.println(prevNode.getData());
}
head = prevNode;
}
}
As you can see, I added the reverse function in the class only.
But when I tried actually using the class it gave NullPointerException after I tried to reverse it.
To check the functionality I used another class called TEST. The code is as follows:
public class TEST
{
public static void main(String[] args)
{
SingleLinkedList<Integer> list = new SingleLinkedList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
System.out.println(list.toString());
list.reverse();
System.out.println(list.toString());
}
}
The output is as follows:
1 2 3 4 5
null
1
2
3
4
5
Exception in thread "main" java.lang.NullPointerException
at SingleLinkedList.toString(SingleLinkedList.java:129)
at TEST.main(TEST.java:20)
I tried to print the value of prevNode to check whether its not taking values...but it is.
What to do?
Actually, your reverse method looks fine.
The problem is your toString() method.
When you create a new list, you create an initial element whose data is null.
Your toString method skips that first element, so it works fine as long as you don't reverse the list.
But when you reverse the list, that null element becomes the last element, and when you call output+=current.getData().toString()+" "; for that last element when current.getData() is null, you get NullPointerException.
You have several options :
Your reverse method can keep the initial null element first (i.e. reverse the rest of the list, but keep the head the same). This way toString can remain unchanged.
Eliminate the initial null element. Then your toString method doesn't have to skip anything.
Keeping the null element first :
public void reverse()
{
Node current = head.getNext();
Node prevNode = null;
Node nextNode;
while(current!=null)
{
nextNode = current.getNext();
current.setNext(prevNode);
prevNode = current;
current = nextNode;
System.out.println(prevNode.getData());
}
head.setNext(prevNode);
}
The problem is in your SingleLinkedList.java toString() method
Try below it is working fine
public String toString() {
Node current = head;
String output = "";
while (current != null) {
// output += current.getData().toString() + " ";
output += String.valueOf(current.getData()) + " ";
current = current.getNext();
}
return output;
}
while(current!=null)
This is your problem. When you hit the last node the 'next' node you get is actually null.
Try changing it to
while(current!=null&&current.getNext()!=null)
EDIT: Actually not sure that solution will work. Try putting a conditional at the end of your loop that says:
if(current.getNext()==null)
break;
EDIT (again :/):
ok sorry I wasn't thinking straight.
change that final if statement to:
if(current.getNext()==null){
current.setNext(prevNode);
break;
}
The actual nullpointer is in the toString. Here's what you do:
Change the while conditional to
while(current != null&&current.getData()!=null)
Because otherwise if current points to null then you get an exception.
That was exhausting.

Having some trouble using a Linked List and passing elements to the Node

In this specific instance, it takes into account two occasions. One where I'm trying to place a node in the beginning of the Linked List and one where I'm trying to place it in the middle or at the end. Here is my Node Class. If you look at my INSERT method, the part that is not working is:
Node newNode = new Node();
newNode.setExponent(element);
class Node {
private int coefficient;
private int exponent;
private Node link;
// Constructor: Node()
Node(int c, int e) {
// Sets coefficient to c, exponent to e, and link to null
coefficient = c;
exponent = e;
link = null;
}
// Inspectors: getCoefficient(), getExponent(), getLink()
public int getCoefficient() {
// Returns coefficient
return coefficient;
}
public int getExponent() {
// Returns exponent
return exponent;
}
public Node getLink() {
// Returns link
return link;
}
// Modifiers: setCoefficient(), setExponent(), setLink()
public void setCoefficient(int c) {
// Sets coefficient to c
coefficient = c;
}
public void setExponent(int e) {
// Sets exponent to e
exponent = e;
}
public void setLink(Node n) {
// Sets link to n
link = n;
}
}// Ends Node Class
Here is where I'm trying to insert to my Linked List along with some other methods in the class that should help give you an idea of how my code looks.
class List {
private Node head; // Points to first element of the list
private int count; // number of elements in the list
// Constructor:
List() {
// Sets head to null and count to zero
head = null;
count = 0;
}
// Inspectors:
// Returns the number of elements in the list
public int size() {
return count;
}
// Modifiers:
// Inserts element at index in the list. Returns true if successful
public boolean insert(int index, Node element) {
if (index < 0 || index > count)return false;
if (index == 0) {
Node newNode = new Node();
newNode.setExponent(element);
count++;
newNode.setLink(head);
head = newNode;
return true;
}
Node walker = head;
for (int i = 1; i < (index - 1); i++)
walker = walker.getLink();
Node newNode = new Node();
newNode.setExponent(element);
newNode.setLink(walker.getLink());
walker.setLink(newNode);
count++;
return true;
}
Try this:
Assumption: You are trying to insert a Node element into the index of LinkedList
Your insert method with modification.
public boolean insert(int index, Node element) {
//if (index < 0 || index > count)
if (index < 0 || index > count + 1) return false;
if(head == null) {
head = element;
return true;
}
if (index == 0) {
//Node newNode = new Node();
//newNode.setExponent(element);
count++;
element.setLink(head);
//newNode.setLink(head);
head = element;
//head = newNode;
return true;
}
Node walker = head;
//for (int i = 0; i < (index - 1); i++)
for (int i = 1; i < index; i++) {
walker = walker.getLink();
}
//Node newNode = new Node();
//newNode.setExponent(element);
element.setLink(walker.getLink());
//newNode.setLink(walker.getLink());
//walker.setLink(newNode);
walker.setLink(element);
count++;
return true;
}
Sample Test Case:
print method:
void print() {
Node travel = head;
while(travel!= null) {
System.out.println(travel.getExponent() + " " + travel.getCoefficient());
travel = travel.getLink();
}
}
Main method:
public static void main(String args[]) {
Node n1 = new Node(1,2);
List l = new List();
l.insert(0,n1);
Node n2 = new Node(3,2);
l.insert(1,n2);
Node n3 = new Node(4,5);
l.insert(0,n3);
l.print();
}

Linked List Array

I have this school assignment that I'm a little confused about.
Here's what it's saying:
"Write a program that uses the technique of 'chaining' for hashing.
The program will read in the length of an array which will contain the reference to each
linked list that will be generated. Furthermore, all values that are to be stored, is read.
The program shall have a separate function for hashing where the index exists. When the program have generated the linked lists, the theoretical 'load factor' is to be calculated and printed out. The whole array should be easily printed out."
The thing that I'm confused about, is the part about the program will read in the length of an array which will contain the reference to each linked list that will be generated. Is it possible to generate multiple linked lists? In that case, how do you do that?
This is the classes I'm told to use:
public class EnkelLenke {
private Node head = null;
private int numOfElements = 0;
public int getNum()
{
return numOfElements;
}
public Node getHead()
{
return head;
}
public void insertInFront(double value)
{
head = new Node (value, head);
++numOfElements;
}
public void insertInBack(double value)
{
if (head != null)
{
Node this = head;
while (this.next != null)
this = this.next;
this.next = new Node(value, null);
}
else
head = new Node(value, null);
++numOfElements;
}
public Node remove(Node n)
{
Node last = null;
Node this = head;
while (this != null && this != n)
{
last = this;
this = this.next;
}
if (this != null)
{
if (last != null)
last.next = this.next;
else
head = this.next;
this.next = null;
--numOfElements;
return this;
}
else
return null;
}
public Node findNr(int nr)
{
Node this = head;
if (nr < numOfElements)
{
for (int i = 0; i < nr; i++)
this = this.next;
return this;
}
else
return null;
}
public void deleteAll()
{
head = null;
numOfElements = 0;
}
public String printAllElements() {
String streng = new String();
Node this = head;
int i = 1;
while(this != null)
{
streng = streng + this.element + " ";
this = this.findNext();
i++;
if(i > 5)
{
i = 1;
streng = streng + "\n";
}
}
return streng;
}
public double getValueWithGivenNode (Node n)
{
Node this = head;
while (this != null && this != n)
{
this = this.next;
}
if (this == n)
return this.element;
else
return (Double) null;
}
}
public class Node {
double element;
Node next;
public Node(double e, Node n)
{
element = e;
next = n;
}
public double findElement()
{
return element;
}
public Node findNext()
{
return next;
}
}
Your data structure will look something like this (where "LL" is a linked list):
i | a[i]
-------------------------------
0 | LL[obj1 -> obj5 -> obj3]
1 | LL[obj2]
2 | LL[]
... | ...
N-1 | LL[obj4 -> obj6]
At each array index, you have a linked list of objects which hash to that index.
Is it possible to generate multiple linked lists? In that case, how do you do that?
Yes. Create your array, and initialize each element to a new linked list.
EnkelLenke[] a = new EnkelLenke[N];
for ( int i = 0; i < N; i++ ) {
a[i] = new EnkelLenke();
}

deleteBack java program

I am doing some exercises on practice-it website. And there is a problem that I don't understand why I didn't pass
Write a method deleteBack that deletes the last value (the value at the back of the list) and returns the deleted value. If the list is empty, your method should throw a NoSuchElementException.
Assume that you are adding this method to the LinkedIntList class as defined below:
// A LinkedIntList object can be used to store a list of integers.
public class LinkedIntList {
private ListNode front; // node holding first value in list (null if empty)
private String name = "front"; // string to print for front of list
// Constructs an empty list.
public LinkedIntList() {
front = null;
}
// Constructs a list containing the given elements.
// For quick initialization via Practice-It test cases.
public LinkedIntList(int... elements) {
this("front", elements);
}
public LinkedIntList(String name, int... elements) {
this.name = name;
if (elements.length > 0) {
front = new ListNode(elements[0]);
ListNode current = front;
for (int i = 1; i < elements.length; i++) {
current.next = new ListNode(elements[i]);
current = current.next;
}
}
}
// Constructs a list containing the given front node.
// For quick initialization via Practice-It ListNode test cases.
private LinkedIntList(String name, ListNode front) {
this.name = name;
this.front = front;
}
// Appends the given value to the end of the list.
public void add(int value) {
if (front == null) {
front = new ListNode(value, front);
} else {
ListNode current = front;
while (current.next != null) {
current = current.next;
}
current.next = new ListNode(value);
}
}
// Inserts the given value at the given index in the list.
// Precondition: 0 <= index <= size
public void add(int index, int value) {
if (index == 0) {
front = new ListNode(value, front);
} else {
ListNode current = front;
for (int i = 0; i < index - 1; i++) {
current = current.next;
}
current.next = new ListNode(value, current.next);
}
}
public boolean equals(Object o) {
if (o instanceof LinkedIntList) {
LinkedIntList other = (LinkedIntList) o;
return toString().equals(other.toString()); // hackish
} else {
return false;
}
}
// Returns the integer at the given index in the list.
// Precondition: 0 <= index < size
public int get(int index) {
ListNode current = front;
for (int i = 0; i < index; i++) {
current = current.next;
}
return current.data;
}
// Removes the value at the given index from the list.
// Precondition: 0 <= index < size
public void remove(int index) {
if (index == 0) {
front = front.next;
} else {
ListNode current = front;
for (int i = 0; i < index - 1; i++) {
current = current.next;
}
current.next = current.next.next;
}
}
// Returns the number of elements in the list.
public int size() {
int count = 0;
ListNode current = front;
while (current != null) {
count++;
current = current.next;
}
return count;
}
// Returns a text representation of the list, giving
// indications as to the nodes and link structure of the list.
// Detects student bugs where the student has inserted a cycle
// into the list.
public String toFormattedString() {
ListNode.clearCycleData();
String result = this.name;
ListNode current = front;
boolean cycle = false;
while (current != null) {
result += " -> [" + current.data + "]";
if (current.cycle) {
result += " (cycle!)";
cycle = true;
break;
}
current = current.__gotoNext();
}
if (!cycle) {
result += " /";
}
return result;
}
// Returns a text representation of the list.
public String toString() {
return toFormattedString();
}
// ListNode is a class for storing a single node of a linked list. This
// node class is for a list of integer values.
// Most of the icky code is related to the task of figuring out
// if the student has accidentally created a cycle by pointing a later part of the list back to an earlier part.
public static class ListNode {
private static final List<ListNode> ALL_NODES = new ArrayList<ListNode>();
public static void clearCycleData() {
for (ListNode node : ALL_NODES) {
node.visited = false;
node.cycle = false;
}
}
public int data; // data stored in this node
public ListNode next; // link to next node in the list
public boolean visited; // has this node been seen yet?
public boolean cycle; // is there a cycle at this node?
// 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) {
ALL_NODES.add(this);
this.data = data;
this.next = next;
this.visited = false;
this.cycle = false;
}
public ListNode __gotoNext() {
return __gotoNext(true);
}
public ListNode __gotoNext(boolean checkForCycle) {
if (checkForCycle) {
visited = true;
if (next != null) {
if (next.visited) {
// throw new IllegalStateException("cycle detected in list");
next.cycle = true;
}
next.visited = true;
}
}
return next;
}
}
// YOUR CODE GOES HERE
}
My work so far is this:
public int deleteBack(){
if(front==null){
throw new NoSuchElementException();
}else{
ListNode current = front;
while(current!=null){
current = current.next;
}
int i = current.data;
current = null;
return i;
}
}
Don't you want to iterate until the current.next is != null?
What you have now passes the entire list, and your last statements do nothing, since current is null already.
Think about the logic you have here
while(current!=null){
current = current.next;
}
When that loop exits, current == null, and then you try to access current's data. Does this point you in the right direction?
// This is the quick and dirty
//By Shewan
public int deleteBack(){
if(size()== 0){ throw new NoSuchElementException(); }
if(front==null){ throw new NoSuchElementException();
}else{
if(front.next == null){
int i = front.data;
front = null;
return i;
}
ListNode current = front.next;
ListNode prev= front;
while(current.next!=null){
prev = current;
current = current.next;
}
int i = current.data;
prev.next = null;
return i;
}
}

Categories