Return top element in a stack - java

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();
}
}

Related

How do I add elements (integers or string) in the middle of my doubly-linked list? -Java

This code allows me to create a linked list and I want to be able to add elements
between two nodes.
I'm having trouble understanding how to set it up so I can insert a number between 40 and 30.
public class DoublyLinkedList<E> {
private static class Node<E> {
//Node Fields
private E element;
private Node<E> prev;
private Node<E> next;
// Node Constructor
public Node(E e, Node<E> p, Node<E> n) {
this.element = e;
this.prev = p;
this.next = n;
}
// Node Methods
public E getElement() {
return element;
}
public Node<E> getPrev() {
return this.prev;
}
public Node<E> getNext() {
return this.next;
}
public void setPrev(Node<E> p) {
this.prev = p;
}
public void setNext(Node<E> n) {
this.next = n;
}
}
// DLinkedList Fields
private Node<E> header;
private Node<E> trailer;
int size;
// DLinkedList Constructor
public DoublyLinkedList() {
this.header = new Node<>(null, null, null);
this.trailer = new Node<>(null, this.header, null);
this.header.setNext(this.trailer);
}
// DLinkedList Methods
public int size() {
return this.size;
}
public E first() {
if (isEmpty()) {
return null;
}
return this.header.next.getElement();
}
public E last() {
if (isEmpty()) {
return null;
}
return this.trailer.prev.getElement();
}
public boolean isEmpty() {
return size == 0;
}
public void addFirst(E e) {
addBetween(e, this.header, this.header.getNext());
}
public void addLast(E e) {
addBetween(e, this.trailer.getPrev(), this.trailer);
}
public void addBetween(E e, Node<E> predecessor, Node<E> successor) {
Node<E> newest = new Node<>(e, predecessor, successor);
predecessor.setNext(newest);
successor.setPrev(newest);
this.size++;
}
public E removeFirst() {
if (this.isEmpty()) {
return null;
}
return this.remove(header.getNext());
}
public E removeLast() {
if (this.isEmpty()) {
return null;
}
return this.remove(trailer.getPrev());
}
public E remove(Node<E> e) {
e.next.setPrev(e.prev);
e.prev.setNext(e.next);
this.size--;
return e.getElement();
}
public String toString() {
StringBuilder sb = new StringBuilder("(");
Node<E> walk = this.header.next;
while (walk != this.trailer) {
sb.append(walk.element);
if (walk.next != this.trailer)
sb.append("--> ");
walk = walk.next;
}
sb.append(")");
return sb.toString();
}
// Node myList = new Node<E>(null, trailer, header);
// myList.e.addFirst
// Node myList2 = new Node<E>(null, 1, null);
}
class Main {
public static void main(String[] args) {
// create a DoublyLinkedList object
DoublyLinkedList Node = new DoublyLinkedList();
// Add nodes to the list
Node.addFirst(10);
Node.addFirst(20);
Node.addFirst(30);
Node.addFirst(40);
Node.addFirst(50);
Node.removeFirst();
Node.removeLast();
//Node.addBetween(Node, null, null);
// print the nodes of DoublyLinkedList
System.out.println(Node);
}
}
Start by changing addBetween to return the node.
public Node<E> addBetween(E e, Node<E> predecessor, Node<E> successor) {
Node<E> newest = new Node<>(e, predecessor, successor);
predecessor.setNext(newest);
successor.setPrev(newest);
this.size++;
return newest;
}
Change addFirst and addLast to return that node. I'll only show addFirst:
public Node<E> addFirst(E e) {
return addBetween(e, this.header, this.header.getNext());
}
Save the nodes for 30 and 40:
Node<Integer> node30 = Node.addFirst(30);
Node<Integer> node40 = Node.addFirst(40);
Then you can use addBetween:
Node.addBetween(newNumber, node30, node40);
You need not expose the class Node and indeed you made it private.
But then you cannot navigate by Node, just by E. So remove(Node) is not possible as public method.
Node's methods could be private too.
Node need not be parametrized by <E>. That can even give serious programming problems, as there then are two Es. Remove it.
addBetween is nicely symmetric, but successor is redundant. I would remove it as parameter and make it a local variable.
Rename the local variable Node to list.
So:
private E removeNode(Node node) {
node.next.setPrev(node.prev);
node.prev.setNext(node.next);
size--;
return node.getElement();
}
private Optional<Node> find(E element) {
for (Node node = header.next; node != trailer; node = node.next) {
if (node.element == element) {
return Optional.of(node);
}
}
return Optional.empty();
}
public boolean remove(E e) {
Optional<Node> nodeOpt = find(e);
nodeOpt.ifPresent(n -> removeNode(n));
return nodeOpt.isPresent();
}
The same for an insertBefore(E), insertAfter(E).

How to implement compareTo() for two nodes in a linked list

I am new to Java and I am trying to implement the Comparable interface for a linked list. I have a standard linked list.
public class LinkedList<E extends Comparable<E>>{
private static class Node<T> {
private T value;
private Node<T> next;
private Node(T value, Node<T> next) {
this.value = value;
this.next = next;
}
}
private Node<E> head;
private int size=0;
public boolean isEmpty() {
return head == null;
//or
//return size == 0;
}
public void addFirst(E elem) {
if (elem == null) {
throw new NullPointerException();
}
head = new Node<E>(elem, head);
size++;
}
public void addLast(E elem) {
if (elem == null) {
throw new NullPointerException();
}
if (head == null) {
head = new Node<E>(elem, null);
} else {
Node<E> current = head;
while (current.next != null) {
current = current.next;
}
current.next = new Node<E>(elem, null);
}
size++;
}
//adding at a specific index
public void add(E elem, int index) {
if (elem == null) {
throw new NullPointerException();
}
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException(Integer.toString(index));
}
if (index == 0) {
head = new Node<E>(elem, head);
} else {
Node<E> p = head;
for (int i=0; i<(index-1); i++) {
p = p.next;
}
p.next = new Node<E>(elem, p.next);
}
size++;
}
public E removeFirst() {
if (head == null) {
throw new NullPointerException();
}
E saved = head.value;
head = head.next;
size--;
return saved;
}
public E removeLast() {
if (head == null) {
throw new NullPointerException();
}
E saved;
if (head.next == null) {
saved = head.value;
head = null;
} else {
Node<E> p = head;
while (p.next.next != null) {
p = p.next;
}
saved = p.next.value;
p.next = null;
}
size--;
return saved;
}
public int size() {
return size;
}
public String toString() {
String str = "[";
Node<E> p = head;
while (p!=null) {
if (p != head) {
str += ", ";
}
str += p.value;
p = p.next;
}
str += "]";
return str;
}
public int compareTo(Node<E> other){
return Integer.compare(this.value,other.value);
}
}
Currently I am assuming the contents of the list are of type int. When I try to compile, I get the error as
LinkedList.java:144: error: cannot find symbol
return Integer.compare(this.value,other.value);
^
Based on what I can understand, it's because I am trying to compare Objects of type Node and not linkedList, therefore "this" is referring linkedList. I am not sure how I can change my code to be able to compare two nodes. Any help or suggestions is appreciated.
Edit:
Is my general methodology incorrect or just my implementation? Is there another way I should implement compareTo? e.g. Add it as a method in the class node?
value is a field in Node and this in your current compareTo method refers to a the linked list object.
You could make the Node class to implement Comparable as below:
public static class Node<T> implements Comparable<Node<T>> {
// rest of the code
#Override
public int compareTo(Node<T> other) {
// this.value is accessible.
}
}
Now in your LinkedList class write another compareTo method (or any other name as this method is not related to Comparable.compareTo) which would invoke the above.
public int compareTo(Node<E> other) {
return this.head.compareTo(other);
}
NOTE: In your current code, you haven't actually "implemented" the Comparable interface. You have only mentioned that the generic type E is a Comparable type.
You didn't understand this<E extends Comparable<E>>,There are two solutions
1.
public class LinkedList<E extends Comparable<E>>{
//public class LinkedList<E extends Integer>{
private static class Node<T> {
private T value;
private Node<T> next;
private Node(T value, Node<T> next) {
this.value = value;
this.next = next;
}
}
private Node<E> head;
private int size=0;
public int compareTo(Node<E> other){
return this.head.value.compareTo(other.value);
//return Integer.compare(this.head.value, other.value);
}
}
//public class LinkedList<E extends Comparable<E>>{
public class LinkedList<E extends Integer>{
private static class Node<T> {
private T value;
private Node<T> next;
private Node(T value, Node<T> next) {
this.value = value;
this.next = next;
}
}
private Node<E> head;
private int size=0;
public int compareTo(Node<E> other){
//return this.head.value.compareTo(other.value);
return Integer.compare(this.head.value, other.value);
}
}

How to change the order of a single linkedlist queue in java?

public class Node<E> {
private E element;
public Node<E> next;
int data;
Node(int d)
{
data = d;
next = null;
}
public Node(E element, Node<E> next) {
this.element = element;
this.next = next;
}
public E getElement() {
return element;
}
public Node<E> getNext() {
return next;
}
public void setElement(E element) {
this.element=element;
}
public void setNext(Node<E> n) {
next = n;
}
public void displayNode(){
System.out.print(element+ " ");
}
}
public class SinglyLinkedList<E> {
private Node<E> head;
private Node<E> tail;
private int size;
public SinglyLinkedList() {
head = tail = null;
size = 0;
}
public SinglyLinkedList(Node<E> head, Node<E> tail) {
this.head = head;
this.tail = tail;
}
public Node<E> getHead() {
return head;
}
public Node<E> getTail() {
return tail;
}
public void setHead(Node<E> head) {
this.head = head;
}
public void setTail(Node<E> tail) {
this.tail = tail;
}
public boolean isEmpty() {
if (head == null) {
return true;
}
return false;
}
public E first() {
return head.getElement();
}
public E last() {
return tail.getElement();
}
public void addFirst(E e) {
if (head == null) {
head = tail = new Node(e, null);
} else {
Node<E> newest = new Node(e, head);
head = newest;
}
size++;
}
public void addLast(E e) {
if (tail == null) {
head = tail = new Node(e, null);
} else {
Node<E> newest = new Node(e, null);
tail.setNext(newest);
tail = newest;
}
size++;
}
public E removeFirst() {
E e = head.getElement();
head = head.getNext();
size--;
return e;
}
#Override
public String toString() {
Node<E> tmp = head;
String s = "";
while (tmp != null) {
s += tmp.getElement();
tmp=tmp.getNext();
}
return s;
}
public void displayList() {
Node current = head;
while (current != null) {
current.displayNode();
current = current.next;
}
}
}
public interface Queue<E> {
int size();
boolean isEmpty();
void enqueue( );
E first();
E dequeue();
}
public class LinkedQueue<E> implements Queue<E> {
private SinglyLinkedList<E> list = new SinglyLinkedList<>();
public LinkedQueue() {
}
public int size() {
return list.size();
}
public boolean isEmpty() {
return list.isEmpty();
}
public void enqueue(E element) {
list.addLast(element);
}
public E first() {
return list.first();
}
public E dequeue() {
return list.removeFirst();
}
#Override
public void enqueue() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools |list.addLast(element);
}
public void displayQueue() {
list.displayList();
System.out.println();
}
public class Main {
public static void main(String[] args) {
LinkedQueue list = new LinkedQueue();
list.enqueue(sam);
list.enqueue(adams);
list.enqueue(john);
list.enqueue(isac);
list.enqueue(gad);
System.out.print("\n Linked list before calling swapNodes() ");
list.displayQueue();
}}
How to change the order of these names in the queue?
I have try to put function that swap nodes in the singlylinkedlist class but it didn't work.i m confused in which layer should i make this function in the linkedqueue class or the singlylinkedlist class or in the main class. yes i want just to swap names in the queue as simple as that.
UPDATED ANSWER
I modified your Node and NodeList Classes in a way which is easier to understand. I also kept similar private values and similar methods for those classes.
public class JavaApplication287 {
public static class Node{
private Node node;
private Node nextNode;
int data;
Node(int d){
data = d;
nextNode = null;
}
public Node getNode(){return node;}
public void setNode(Node someNode){node = someNode;}
public Node getNextNode(){return nextNode;}
public void setNextNode(Node someNextNode){nextNode = someNextNode;}
public int getData(){return data;}
public void setData(int d){data = d;}
public void printNode(){System.out.println(data);}
}
public static class NodeLinkedList{
private Node head;
private Node tail;
private int size;
NodeLinkedList(Node nodeHead, Node nodeTail, int s){
this.head = nodeHead;
this.tail = nodeTail;
this.size = s;
}
public Node getHead(){return head;}
public void setHead(Node n){head = n;}
public Node getTail(){return tail;}
public void setTail(Node n){tail = n;}
public int getSize(){return size;}
public void setSize(int n){size = n;}
public void printNodeList(){
System.out.println("Head: " + head.getData());
Node current = head;
while (current.nextNode != null){
System.out.println(current.data);
current = current.getNextNode();
}
System.out.println("Tail: " + tail.getData());
}
}
public static void main(String[] args) {
// create Sample Nodes
Node zero = new Node(0);
Node one = new Node(1);
Node two = new Node(2);
Node three = new Node(3);
Node four = new Node(4);
Node five = new Node(5);
//Link Them
zero.setNextNode(one);
one.setNextNode(two);
two.setNextNode(three);
three.setNextNode(four);
four.setNextNode(five);
//Create the Linked Node List with head = one & tail = five
NodeLinkedList myNodeLinkedList = new NodeLinkedList(zero, five, 6);
//Print Current LinkedNodes
myNodeLinkedList.printNodeList();
//Invert the NodeLinkedList
Node position = myNodeLinkedList.getHead(); //Node we look at
Node prev = null; // Store the prev Node
Node node = null; // Temp Node of the next Node in the Linked List
for (int i=0; i< myNodeLinkedList.getSize(); i++){
node = position.getNextNode(); //Store the Next Node so we do not lose access to it
position.setNextNode(prev); // Update current Node's NextNode value
prev = position; // Set previous Node as the Node we are currently looking at
position = node; // Move our position to the next Node
}
//Invert Head and Tail
Node temp = myNodeLinkedList.getHead();
myNodeLinkedList.setHead(myNodeLinkedList.getTail());
myNodeLinkedList.setTail(temp);
//Print Current LinkedNodes
myNodeLinkedList.printNodeList();
}
}
This is working code and here is the output I get,
run:
Head: 0
0
1
2
3
4
Tail: 5
Head: 5
5
4
3
2
1
Tail: 0
BUILD SUCCESSFUL (total time: 0 seconds)
Hope it helps,

Class Cast Error trying to use compareTo with node and elements in a linked list

I've looked at a bunch of the questions in this area and can't find one that solves my problem specifically.
Basically, this is a homework assigment where I have a linked list with nodes, which hold an element. The node class (LinearNode) and the element class (Golfer) both implement Comparable and override the compareTo method. However, the runtime fails trying to add a new node to the list (first node is added fine) with a class cast exception: supersenior.LinearNode cannot be cast to supersenior.Golfer. I don't know why it's trying to take the node and compare it to an element of the node to be compared...i've even tried explicitly casting. The following error is observed:
Exception in thread "main" java.lang.ClassCastException: supersenior.LinearNode cannot be cast to supersenior.Golfer
at supersenior.Golfer.compareTo(Golfer.java:12)
at supersenior.LinearNode.compareTo(LinearNode.java:80)
at supersenior.LinearNode.compareTo(LinearNode.java:80)
at supersenior.LinkedList.add(LinkedList.java:254)
at supersenior.SuperSenior.main(SuperSenior.java:100)
Any help would be greatly appreciated. Thanks!
LinkedList class:
package supersenior;
import supersenior.exceptions.*;
import java.util.*;
public class LinkedList<T> implements OrderedListADT<T>, Iterable<T>
{
protected int count;
protected LinearNode<T> head, tail;
/**
* Creates an empty list.
*/
public LinkedList()
{
count = 0;
head = tail = null;
}
public T removeFirst() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException ("List");
LinearNode<T> result = head;
head = head.getNext();
if (head == null)
tail = null;
count--;
return result.getElement();
}
public T removeLast() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException ("List");
LinearNode<T> previous = null;
LinearNode<T> current = head;
while (current.getNext() != null)
{
previous = current;
current = current.getNext();
}
LinearNode<T> result = tail;
tail = previous;
if (tail == null)
head = null;
else
tail.setNext(null);
count--;
return result.getElement();
}
public T remove (T targetElement) throws EmptyCollectionException,
ElementNotFoundException
{
if (isEmpty())
throw new EmptyCollectionException ("List");
boolean found = false;
LinearNode<T> previous = null;
LinearNode<T> current = head;
while (current != null && !found)
if (targetElement.equals (current.getElement()))
found = true;
else
{
previous = current;
current = current.getNext();
}
if (!found)
throw new ElementNotFoundException ("List");
if (size() == 1)
head = tail = null;
else if (current.equals (head))
head = current.getNext();
else if (current.equals (tail))
{
tail = previous;
tail.setNext(null);
}
else
previous.setNext(current.getNext());
count--;
return current.getElement();
}
public boolean contains (T targetElement) throws
EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException ("List");
boolean found = false;
Object result;
LinearNode<T> current = head;
while (current != null && !found)
if (targetElement.equals (current.getElement()))
found = true;
else
current = current.getNext();
return found;
}
public boolean isEmpty()
{
return (count == 0);
}
public int size()
{
return count;
}
public String toString()
{
LinearNode<T> current = head;
String result = "";
while (current != null)
{
result = result + (current.getElement()).toString() + "\n";
current = current.getNext();
}
return result;
}
public Iterator<T> iterator()
{
return new LinkedIterator<T>(head, count);
}
public T first()
{
return head.getElement();
}
public T last()
{
return tail.getElement();
}
#Override
public void add (T element)
{
LinearNode<T>node = new LinearNode<T>();
node.setElement(element);
if(isEmpty())
{
head = node;
if(tail == null)
tail = head;
//node.setNext(head);
//head.setPrevious(node);
//head.setElement((T) node);
count++;
}
else
{
for(LinearNode<T> current = head; current.getNext() != null; current = current.getNext())
if(node.compareTo((T) current) >= 0)
{
current.setPrevious(current);
current.setNext(current);
}
else
{
current.setPrevious(node);
}
tail.setNext(node);
}
}
}
LinearNode class:
package supersenior;
public class LinearNode<E> implements Comparable<E>
{
private LinearNode<E> next, previous;
public E element;
public LinearNode()
{
next = null;
element = null;
}
public LinearNode (E elem)
{
next = null;
element = elem;
}
public LinearNode<E> getNext()
{
return next;
}
public void setNext (LinearNode<E> node)
{
next = node;
}
public E getElement()
{
return element;
}
public void setElement (E elem)
{
element = elem;
}
#Override
public int compareTo(E otherElement) {
return ((Comparable<E>) this.element).compareTo(otherElement);
}
public LinearNode<E> getPrevious()
{
return previous;
}
public void setPrevious (LinearNode<E> node)
{
previous = node;
}
}
The element class (Golfer):
package supersenior;
public class Golfer implements Comparable<Golfer>{
Golfer imaGolfer;
String name;
int tourneys;
int winnings;
double avg;
public Golfer(String attr[]){
this.name = attr[0];
this.tourneys = Integer.parseInt(attr[1]);
this.winnings = Integer.parseInt(attr[2]);
this.avg = findAvg(winnings, tourneys);
}
private double findAvg(int winnings, int tourneys){
double a = winnings/tourneys;
return a;
}
#Override
public String toString(){
return "Name: " + name + " Tourneys: " + tourneys + " Winnings: " + winnings + " Average: " + avg;
}
#Override
public int compareTo(Golfer golfer) {
if(this.avg <= golfer.avg)
return 1;
if(this.avg == golfer.avg)
return 0;
else
return -1;
}
}
The problem is that you're mixing what's being compared. You're trying to compare the LinearNode object (which holds an E) to an actual E. LinearNode<E> shouldn't implement Comparable<E>; if anything, it might implement Comparable<LinearNode<E>>, and the type parameter should probably be E extends Comparable<E>.
If you want to order LinearNodes based on the ordering of their underlying elements, you should use something like this:
// in LinearNode
public int compareTo(LinearNode<E> otherNode) {
return this.element.compareTo(otherNode.element);
}
(Note that the Java sorted collections don't require elements to implement Comparable, since you can provide a custom Comparator for any of them, but in the case of this assignment it's probably fine to require that E extends Comparable<E>.)
(Note 2: If you're using Generics, any cast, such as your (Comparable<E>), is a red flag; the purpose of the Generics system is to eliminate the need for most explicit casts.)

Nodes, Queues, De-queues

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;
}

Categories

Resources