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
Related
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.
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.
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()));
}
Hey ya'll I am having a little trouble with my singly linked list. I decided to create a simple one because we do not get enough practice during my data structures class and cannot seem to find why I am not getting the right output.
The code is:
package linked_list;
public class LinkedList {
private Node head;
private Node tail; // After figuring out head, come back to this FIXME
private int listSize;
public LinkedList() {
head = new Node(null);
tail = new Node(null);
}
public void addLast(String s) {
Node newNode = new Node(s);
if (head == null) {
addFirst(s);
} else {
while (head.next != null) {
head = head.next;
}
head.next = newNode;
tail = newNode;
}
listSize++;
}
public void addFirst(String s) {
Node newNode = new Node(s);
if (head == null) {
head = newNode;
tail = newNode;
}
else {
newNode.next = head;
head = newNode;
}
listSize++;
}
public Object getFirst() {
return head.data;
}
public Object getLast() {
return tail.data;
}
public void clear() {
head = null;
tail = null;
listSize = 0;
}
public Object peek() {
try {
if (head == null) {
throw new Exception ("The value is null");
}
else {
return head;
}
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
public int size() {
return listSize;
}
// This class has the ability to create the nodes that are used
// in the Linked List.
private class Node {
Node next;
Object data;
public Node(String value) {
next = null;
data = value;
}
public Node(Object value, Node nextValue) {
next = nextValue;
data = value;
}
public Object getData() {
return data;
}
public void setData(Object dataValue) {
data = dataValue;
}
public Node getNext() {
return next;
}
public void setNext(Node nextValue) {
next = nextValue;
}
}
}
Now here is my driver that I created to run a simple little operation:
package linked_list;
public class LinkedListDriver {
public static void main(String[] args) {
LinkedList list1 = new LinkedList();
list1.clear();
list1.addLast("This goes last");
list1.addFirst("This goes first");
list1.addLast("Now this one goes last");
System.out.println(list1.getFirst());
System.out.println(list1.getLast());
}
}
My output is this:
This goes last
Now this one goes last
I guess my question is why am I not getting the answer This goes first from my getFirst() method. It seems to be something wrong with the order or structure of that method but I cannot pinpoint it.
When you are in the else in the addLast, you are changing the reference to head. You should use another reference pointer to traverse the list when adding in the else.
Also, your list size should only be incremented in the else in addLast because you are incrementing twice otherwise (once in addFirst and again after the if-else in addLast).
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;
}
}
}