Copying Linked List Recursively (Java) - java

End of a long night and I'm having trouble with copying a linked list recursively, I was able to do so with a simple iterative method, but I am having trouble with a stack overflow error when I try to set it up with recursion. Yet, this makes sense to me conceptually. Can anyone steer me in the right direction? This is what I have so far:
public LinkedList<E> createCopyRecursive(Node<E> aNode) {
LinkedList<E> copyList = new LinkedList<E>();
copyList.myStart = myStart;
if (copyList.size() == 0) {
aNode = myStart.getLink();
}
if (aNode.getLink() == null) {
return copyList;
}
else {
copyList.add(aNode.getValue());
return createCopyRecursive(aNode.getLink());
}
}

You're creating a new LinkedList every time you recurse into the method.
I suspect you want to instantiate it outside the method, pass it in and add to it each time through.

I think it can be as simple as this:
private LinkedList<E> copyRecursive(final Node<E> node, final LinkedList<E> accumulator) {
if (node == null) {
// all nodes traversed, return the result.
return accumulator;
}
// add current node to the copy list that is under construction.
accumulator.add(node.getElement());
// recursive call to copy the rest of the nodes to the copy list and return it when finished.
return copyRecursive(node.getNext(), accumulator);
}
First create an empty new linked list, which will contain the copy and then copy node by node into it recursively. You could also not pass an accumulator to it like this:
private LinkedList<E> copyRecursive(final Node<E> node) {
if (node == null) {
return new LinkedList<>();
}
final LinkedList<E> accumulator = copyRecursive(node.getNext());
accumulator.add(node.getElement());
return accumulator;
}
But that will reverse the order of the nodes in the list.
Here is a fully working example with recursive copy and recursive reverse:
public class RecursiveCopyTest {
public static void main(String[] args) {
final LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("first");
linkedList.add("next");
linkedList.add("last");
System.out.println(linkedList);
System.out.println(linkedList.copyRecursive());
System.out.println(linkedList.reverse());
}
private static class LinkedList<E> {
private Node<E> first;
public LinkedList() {
first = null;
}
public LinkedList<E> copyRecursive() {
return copyRecursive(first, new LinkedList<E>());
}
public LinkedList<E> reverse() {
return reverse(first);
}
public void add(E element) {
final Node<E> node = new Node<>(element);
if (first == null) {
first = node;
} else {
Node<E> current = first;
while (current.getNext() != null) {
current = current.getNext();
}
current.setNext(node);
}
}
private LinkedList<E> reverse(final Node<E> node) {
if (node == null) {
return new LinkedList<>();
}
final LinkedList<E> accumulator = reverse(node.getNext());
accumulator.add(node.getElement());
return accumulator;
}
private LinkedList<E> copyRecursive(final Node<E> node, final LinkedList<E> accumulator) {
if (node == null) {
return accumulator;
}
accumulator.add(node.getElement());
return copyRecursive(node.getNext(), accumulator);
}
#Override
public String toString() {
final StringBuilder stringBuilder = new StringBuilder();
Node current = first;
while (current != null) {
stringBuilder.append(current.getElement().toString()).
append(" -> ");
current = current.getNext();
}
stringBuilder.append(" _ ");
return stringBuilder.toString();
}
private static final class Node<E> {
private final E element;
private Node<E> next;
public Node(final E element) {
this.element = element;
}
public E getElement() {
return element;
}
public void setNext(final Node<E> next) {
this.next = next;
}
public Node<E> getNext() {
return next;
}
}
}
}

If you want to use a recursive method to copy your linked list, I think you should first initialize copyList in another mehod that calls createCopyRecursive().
createCopy(Node<E> aNode) {
LinkedList<E> copyList = new LinkedList<E>();
createCopyRecursive(aNode, copyList) {
....
}
}

Rather than passing around whole linkedlist object you can just worry about head node.
Call to recursive method copy()
Node<Integer> copiedHead = copy(head);
Recursive method copy, accepts the head node and returns the copied head node.
private static Node<Integer> copy(Node<Integer> head) {
if(head == null){
return null;
}
return new Node<>(head.getData(), copy(head.getNext()));
}

Related

FIFO queue structure based on a singly linked list

In the java course I'm following right now, I'm required to implement a FIFO queue structure based on a singly linked list. I have to implement interface and override 3 methods: add, poll and peek.
I'm stuck with poll and peek and can not get an Object in return statement. Or may be there is another way to do it. For any help would be very grateful.
add -Use add() method to add elements into the Queue
poll - Fetching and removing the element at the head of the queue
peek- as pool without removing
public class Queue<T> implements Queue2<T> {
Node<T> head;
Node<T> tail;
int size;
#Override
public boolean add(T e) {
Node<T> node = new Node(e);
if (head == null) {
head = node;
tail = node;
} else {
tail.next = node;
tail = node;
node.next = null;
}
size++;
return true;
}
#Override
public T poll() {
if (size == 0)
return null;
else {
T obj = head.getObject();
head = head.next;
if (head == null) {
tail = null;
}
size--;
return obj;
}
}
#Override
public T peek() {
if (head == null)
return null;
else {
return head.getObject();
}
}
class Node<T> {
Node<T> next;
Node<T> value;
public <T> Node(T value) {
}
public T getObject() {
**return null;** // what should be returned here?
}
}
}
public static void main(String[] args) {
Queue<String> queue1 = new Queue<>();
queue1.add("finns");
queue1.add("bella");
queue1.add("ssara");
queue1.add("nanna");
queue1.add("anna");
System.out.println(queue1.peek());
System.out.println(queue1.poll());
class Node<T> {
Node<T> next;
T value;
public Node(T value) {
this.value=value;
}
public T getObject() {
return value;
}
}
The value in Node is your object so should be of type T , not Node<T>.
Remove the <T> from the constructor otherwise you are defining a new T and the assignment this.value=value; will not work.

How to remove from a Linked list in Java?

So I wrote my own linked list (and list node) in Java as a part of a homework.
Now, I'm trying to erase entries, but the function is not working.
I know the concept:
Search for node keeping the previous;
Tell previous node to point to next node;
Return or stop using the node so GC erases it.
For some reason it is not working. I can delete the node with the same value over and over. I'm afraid it is something related to Java pointers.
The code:
Node:
public class SimpleNode<E> {
private E value;
private SimpleNode<E> next;
public SimpleNode() {
this.value = null;
this.next = null;
}
public NoSimples(E data, SimpleNode<E> ref) {
this.value = data;
this.next = ref;
}
// Getters and Setters
}
List:
public class LinkedList<E> implements Iterable<SimpleNode<E>> {
private SimpleNode<E> head;
private int size = 0;
public LinkedList() {
this.head = new SimpleNode<E>();
}
public void add(SimpleNode<E> node) {
this.addFirst(node.getValue());
}
public void addFirst(E item) {
SimpleNode<E> nonde = new SimpleNode<E>(item, this.head);
this.head = node;
size++;
}
public void add(E value) {
this.addFirst(value);
}
public SimpleNode<E> removeFirst() {
SimpleNode<E> node = this.head;
if (node == null) {
return null;
} else {
this.head = node.getNext();
node.setNext(null);
this.size--;
return node;
}
}
public SimpleNodes<E> remove(E value) {
SimpleNode<E> nodeAnt = this.head;
SimpleNode<E> node = this.head.getNext();
while (node != null) {
if (node.getValue()!= null && node.getValue().equals(value)) {
nodeAnt.setNext(node.getNext());
node.setNext(null);
return node;
}
nodeAnt = node;
node = node.getNext();
}
return null;
}
// Other irrelevant methods.
}
Multiple Problems :
Think if you have a list 1,2,3,4. Now, if you try to remove 1, your code fails.
nodeAnt = node should be nodeAnt = nodeAnt.getNext(). Remember, the're all references, not Objects
Also, a recursive way might be easier to understand. For example, Here is how I implemented it
public void remove(E e){
prev = head;
removeElement(e, head);
System.gc();
}
private void removeElement(E e, Node currentElement) {
if(currentElement==null){
return;
}
if(head.getData().equals(e)){
head = head.getNext();
size--;
}else if(currentElement.getData().equals(e)){
prev.setNext(currentElement.getNext());
size--;
}
prev = prev.getNext();
removeElement(e, currentElement.getNext());
}
Note: I delete all occurrences of the Element, as I needed it. You may need it to be different.

convert below singly Linked list to doubly linked list

I already wrote a small program of single linked list with add and traverse method in that. Now I want to convert it into a doubly linked list. I know all the concept of doubly linked list but I am facing little difficulty to implement it in my program.
public class SingleLinkList<T> {
private Node<T> head;
private Node<T> tail;
public void add(T element)
{
Node<T> nd = new Node<T>();
nd.setValue(element);
if (head==null)
{
head = nd;
tail = nd;
}
else
{
tail.setNextRef(nd);
tail = nd;
}
}
public void traverse(){
Node<T> tmp = head;
while(true){
if(tmp == null){
break;
}
System.out.println(tmp.getValue());
tmp = tmp.getNextRef();
}
}
public static void main (String args[])
{
SingleLinkList<Integer> s1 = new SingleLinkList<Integer>();
s1.add(2);
s1.add(3);
s1.add(3);
s1.traverse();
}
}
class Node<T> {
private T value;
private Node<T> nextRef;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public Node<T> getNextRef() {
return nextRef;
}
public void setNextRef(Node<T> nextRef) {
this.nextRef = nextRef;
}
public int compareTo(T arg)
{
if (arg==this.value)
{
return 0;}
else
{return 1;}
}
}
Add a Node<T> prevRef field to your list class with appropriate getters and setters and then add this method:
public void linkReverse(Node<T> head) {
if (head == null) {
return;
}
head.setPrevRef(null);
if (head.getNextRef() == null) {
return;
}
Node<T> prev = head;
Node<T> curr = head.getNextRef();
while (curr != null) {
curr.setPrevRef(prev);
prev = curr;
curr = curr.getNextRef();
}
}
This method will walk down a currently singly linked list and will link each node in reverse, leaving the list doubly linked.
Of course, you would need to modify the other methods as well, but this is at least a good starting point.
just add private Node<T> prevRef; instance variable to Node class, and set it during add() method. I suggest that traverse() will receive a boolean (or even better, enum) direction argument

Singly Linked List Implementation

Alright, I'm trying to implement a (Singly) Linked List via my textbook (Goodrich & Tamassia, Algorithm Design, 2001), and so far so good.
Now, the problem I'm running into, is that I cannot test it properly For example, if I would insert a node via my insertFirst method, how would I still be able to retrieve it to be able to use it for a method like swapElements?
I thought about working via elements, but then I'll run into problems when I have nodes with the same element. So, how should this work in general? I'm sorry if my question is relatively easy or vague, in that case please let me know how I can improve it as I'm fairly new to data structures.
Here's my code;
public class Node<E> implements Position<E> {
private Node<E> next;
private E element;
public Node(Node<E> next, E element) {
this.next = next;
this.element = element;
}
public Node(E element) {
this.element = element;
}
public void setNext(Node<E> next) {
this.next = next;
}
public Node<E> getNext() {
return next;
}
public void setElement(E element) {
this.element = element;
}
public E element() {
return element;
}
public String toString() {
return ("Element: " + element);
}
}
and
public class SinglyLinkedListImp<E> implements List<E> {
private Node<E> head;
private int size;
public SinglyLinkedListImp() {
this.head = null;
this.size = 0;
}
public Node<E> first() {
return head;
}
public Node<E> last() {
Node<E> current = head;
while (current.getNext() != null) {
current = current.getNext();
}
return current;
}
public boolean isFirst(Node<E> n) {
return (head == n);
}
public boolean isLast(Node<E> n) {
return (n.getNext() == null);
}
public Node<E> before(Node<E> n) {
Node<E> current = head;
while (current.getNext() != n) {
current = current.getNext();
}
return current;
}
public Node<E> after(Node<E> n) {
return n.getNext();
}
public Node<E> replaceElements(Node<E> n, E element) {
Node<E> current = head;
Node<E> previous = null;
while (current != n) {
previous = current;
current = current.getNext();
}
Node<E> newLink = new Node<E>(current.getNext(), element);
previous.setNext(newLink);
return current;
}
public void swapElements(Node<E> n, Node<E> k) {
E tmp = n.element();
n.setElement(k.element());
k.setElement(tmp);
}
public void insertFirst(E element) {
head = new Node<E>(head, element);
size++;
}
public void insertLast(E element) {
if (head == null) {
head = new Node<E>(head, element);
} else {
Node<E> current = head;
while (current.getNext() != null) {
current = current.getNext();
}
current.setNext(new Node<E>(null, element));
}
size++;
}
public void insertBefore(Node<E> n, E element) {
Node<E> current = head;
Node<E> previous = null;
while (current.getNext() != n) {
previous = current;
current = current.getNext();
}
previous.setNext(n);
}
public void insertAfter(Node<E> n, E element) {
Node<E> current = head;
while (current != n) {
current = current.getNext();
}
current.setNext(n);
}
public void remove(Node<E> n) {
Node<E> current = head;
Node<E> previous = null;
while (current != n) {
previous = current;
current = current.getNext();
}
previous.setNext(current.getNext());
size--;
}
public int size() {
return size;
}
public boolean isEmpty() {
return (size == 0);
}
public void display() {
if (head == null) {
System.out.println("Empty list.");
} else {
Node<E> current = head;
while (current != null) {
System.out.println(current.toString());
current = current.getNext();
}
}
}
}
Note that the SinglyLinkedListImp class is not totally done yet (some methods will give errors if the list is empty).
I don't think it's needed to provide the code for the two interfaces, but let me know if so.
In your implementation, you have set some methods (like getNext etc) that can be used in order to iterate the collection. A scenario that I can think of it is having retrieved any element of the list in one operation and then apply the editing on the collection based on the element (like swapElements) afterwards.
What I suggest you do though (and will probably make things clear) is add a retrieval method of an element by index:
a method get(int index) would return the element placed on the index given as argument. In fact, the LinkedList collection standard API in Java has such a method. The logic behind this is simple: get the next node till the iteration cycles number reaches the index number.
UPDATE: In order to apply element swapping, obviously the Nodes involved MUST be a part of the list, otherwise there is no meaning in this. As also suggested, swapElements might be basically used for in-class purposes, so unless you have a good reason for it, declare it private.

Iterating over a linked list in Java?

I have been diligently watching YouTube videos in an effort to understand linked lists before my fall classes start and I am uncertain how to proceed with iterating over the following linked list. The 'node' class is from a series of videos (same author), but the 'main' method was written by me. Am I approaching the design of a linked list in an illogical fashion (assuming of course one does not wish to use the predefined LinkedList class since the professor will expect each of us to write our own implementation)?:
class Node
{
private String data;
private Node next;
public Node(String data, Node next)
{
this.data = data;
this.next = next;
}
public String getData()
{
return data;
}
public Node getNext()
{
return next;
}
public void setData(String d)
{
data = d;
}
public void setNext(Node n)
{
next = n;
}
public static String getThird(Node list)
{
return list.getNext().getNext().getData();
}
public static void insertSecond(Node list, String s)
{
Node temp = new Node(s, list.getNext());
list.setNext(temp);
}
public static int size(Node list)
{
int count = 0;
while (list != null)
{
count++;
list = list.getNext();
}
return count;
}
}
public class LL2
{
public static void main(String[] args)
{
Node n4 = new Node("Tom", null);
Node n3 = new Node("Caitlin", n4);
Node n2 = new Node("Bob", n3);
Node n1 = new Node("Janet", n2);
}
}
Thanks for the help,
Caitlin
There are some flaws in your linked list as stated by some of the other comments. But you got a good start there that grasps the idea of a linked list and looks functional. To answer your base question of how to loop over this particular implemention of the linked list you do this
Node currentNode = n1; // start at your first node
while(currentNode != null) {
// do logic, for now lets print the value of the node
System.out.println(currentNode.getData());
// proceed to get the next node in the chain and continue on our loop
currentNode = currentNode.getNext();
}
Maybe this will be useful:
static void iterate(Node head) {
Node current = head;
while (current != null) {
System.out.println(current.getData());
current = current.getNext();
}
}
// or through recursion
static void iterateRecursive(Node head) {
if (head != null) {
System.out.println(head.getData());
iterateRecursive(head.getNext());
}
}
class List {
Item head;
class Item {
String value; Item next;
Item ( String s ) { value = s; next = head; head = this; }
}
void print () {
for( Item cursor = head; cursor != null; cursor = cursor.next )
System.out.println ( cursor.value );
}
List () {
Item one = new Item ( "one" );
Item two = new Item ( "three" );
Item three = new Item ( "Two" );
Item four = new Item ( "four" );
}
}
public class HomeWork {
public static void main( String[] none ) { new List().print(); }
}
Good luck!!
You can have your linked list DS class implement 'Iterable' interface and override hasNext(), next() methods or create an inner class to do it for you. Take a look at below implementation:
public class SinglyLinkedList<T>{
private Node<T> head;
public SinglyLinkedList(){
head = null;
}
public void addFirst(T item){
head = new Node<T>(item, head);
}
public void addLast(T item){
if(head == null){
addFirst(item);
}
else{
Node<T> temp = head;
while(temp.next != null){
temp = temp.next;
}
temp.next = new Node<T>(item, null);
}
}
private static class Node<T>{
private T data;
private Node<T> next;
public Node(T data, Node<T> next){
this.data = data;
this.next = next;
}
}
private class LinkedListIterator implements Iterator<T>{
private Node<T> nextNode;
public LinkedListIterator(){
nextNode = head;
}
#Override
public boolean hasNext() {
return (nextNode.next != null);
}
#Override
public T next() {
if(!hasNext()) throw new NoSuchElementException();
T result = nextNode.data;
nextNode = nextNode.next;
return result;
}
}
}

Categories

Resources