Nodes, Queues, De-queues - java

I'm doing this small project of creating a queue and a de-queue in the same class along with using my own Node class and an interface.
The problem i'm facing is I've done all methods but can't get the method removeLast to work because i'm unable to let rear link to the node before it, after getting removed. Please help me with your suggestions? Thank you.
My node class.
public class Node<T> {
T info;
Node<T> next;
public Node(T element) {
info = element;
next = null;
}
public void setInfo(T element) {
info = element;
}
public T getInfo() {
return info;
}
public void setNext(Node<T> next) {
this.next = next;
}
public Node<T> getNext() {
return next;
}
}
My interface class
public interface DequeInterface<T> {
void addFront(T element);
void addLast(T element);
T removeFront();
T removeLast();
boolean isEmpty();
int getSize();
}
My deque class
import java.util.NoSuchElementException;
public class Deqeue<T> implements DequeInterface {
public Node<T> front;
public Node<T> rear;
int size;
public Deqeue() {
front = null;
rear = null;
size = 0;
}
#Override
public T removeFront() {
if (isEmpty()) {
throw new NoSuchElementException();
}
T element = front.getInfo();
front = front.getNext();
size--;
return element;
}
#Override
public T removeLast() {
if (isEmpty()) {
throw new NoSuchElementException();
}
T element = rear.getInfo();
size--;
return element;
}
#Override
public int getSize() {
return size;
}
#Override
public boolean isEmpty() {
return rear == null;
}
#Override
public void addFront(Object element) {
Node<T> newNode = front;
if (newNode == null) {
rear = front;
}
front = new Node(element);
front.setNext(newNode);
size++;
}
#Override
public void addLast(Object element) {
Node<T> newNode = rear;
if (newNode == null) {
front = rear;
}
rear = new Node(element);
newNode.setNext(rear);
size++;
}
}

The problem is that your list is singly-linked. Unfortunately, removing the last node of a singly-linked list requires traversing the entire list. Some alternatives:
you can make your list doubly-linked
you can use a random-access array instead of a linked list
you could use Okasaki's "purely functional datastructures" deque

You could have your Node have a reference to the previous Node as well. This would create a doubly linked list.
public class Node<T> {
T info;
Node<T> next;
Node<T> prev;
public Node(T element) {
info = element;
next = null;
prev = null;
}
public void setInfo(T element) {
info = element;
}
public T getInfo() {
return info;
}
public void setNext(Node<T> next) {
this.next = next;
}
public Node<T> getNext() {
return next;
}
public void setPrev(Node<T> prev) {
this.prev = prev;
}
public Node<T> getPrev() {
return prev;
}
}
Then in the Deque class change your removeFront and removeLast methods to account for prev
public T removeFront() {
if (isEmpty()) {
throw new NoSuchElementException();
}
T element = front.getInfo();
front = front.getNext();
front.setPrev(null); //<<<--------------------------
size--;
return element;
}
#Override
public T removeLast() {
if (isEmpty()) {
throw new NoSuchElementException();
}
T element = rear.getInfo();
rear.getPrev().setNext(null) //<<<--------------
rear=rear.getPrev(); //<<<--------------
size--;
return element;
}
And of course the addFirst and addLast methods have to be updated as well
#Override
public void addFront(Object element) {
Node<T> newNode = front;
front = new Node(element);
front.setNext(newNode);
if (newNode == null) {
rear = front;
}else{
newNode.setPrev(front);
}
size++;
}
#Override
public void addLast(Object element) {
Node<T> newNode = rear;
rear = new Node(element);
newNode.setNext(rear);
if (newNode == null) {
front = rear;
}else{
newNode.setNext(rear);
}
size++;
}
If you would not be allowed to change the code of Node and only can change the removeLast() method then you could do it like this:
#Override
public T removeLast() {
if (isEmpty()) {
throw new NoSuchElementException();
}
T element = rear.getInfo();
if(rear==first){
rear=null;
first=null;
}else{
Node<T> prev = first;
while(prev.getNext()!=rear){
prev=prev.getNext();
}
rear=prev;
prev.setNext(null);
}
size--;
return element;
}
But this would be rather inefficient as it requires iterating through the whole list from the beginning.

Each node should have a pointer to the next node and to the previous node.

You can make your list doubly linked (extra management and opportunity for bugs), or you can iterate through the list every time you removeLast and set rear to the new last (much worse performance when removing from last especially on large lists.)

The easiest way to go about doing this is to implement a doubly linked list as opposed to a linked list. So your node class will need to keep track of the previous element. You will need to update your add functions to support this. Once completed, your remove last function will look like this:
#Override
public T removeLast() {
if (isEmpty()) {
throw new NoSuchElementException();
}
T element = rear.getInfo();
size--;
rear.getPrev().setNext(null);
rear = rear.getPrev();
return element;
}

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.

Return top element in a stack

I am struggling with the top() method that is supposed to retrieve the top element of the stack, or return null if this stack is empty and return the top element of the stack. How can fix the loop?
public class Stack<E> implements IStack<E> {
Node head;
public E top() {
if (head == null)
return null;
Node<E> tempNode = head;
for (int i = 0; i < size; i++) {
if (tempNode.getmNextNode() == null) {
tempNode.getmElement();
}
tempNode = tempNode.getmNextNode();
}
return tempNode.getmElement();
}
}
My Node class:
public class Node<E> {
private E mElement;
private Node<E> mNextNode;
Node(E data) {
this.setmElement(data);
}
public E getmElement() {
return this.mElement;
}
public void setmElement(E element) {
this.mElement = element;
}
public Node<E> getmNextNode() {
return this.mNextNode;
}
public void setmNextNode(Node<E> node) {
this.mNextNode = node;
}
}
public E top() {
if (head == null)
return null;
Node<E> tempNode = head;
while(tempNode.getmNextNode()!=null) {
tempNode = tempNode.getmNextNode();
}
return tempNode.getmElement();
}
Your top() method is supposed to return the last pushed element into the stack and not the first one. When pushing a new element, the head is referenced to this element. Thus, the head is the top element and would be then returned by your method.
public class Stack<E> implements IStack<E>{
public E top() {
if(head==null){
throw new StackEmptyException();
}
return head.getmElement();
}
}

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.

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.

Linked List Wrong Output Java

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).

Categories

Resources