custom stack peek method in java

343 Views Asked by At

I have an assignment due soon and my professor doesn't actually teach our class. He shows us powerpoints from our textbook and expects us to be able to solve problems with that minor information.

Currently, I am working on custom data structures. He has a custom ListNode and List class that I have included, as well as the custom Stack class he created.

My problem lies where the only code I can add to this is a peek method in the stack class WITHOUT adding any instance variables. I can only add a variable in the peek method. He has not shown us how this is possible, and when I ask for help (I've asked several times) he just says "look at the sample code for the chapter," quite literally verbatim. I need help and he is NOT helping me, so I am hoping someone here can educate me.

I will update this post as I need to, and apologize if not enough information is given up front.

List.java:

import java.util.NoSuchElementException;

// class to represent one node in a list
class ListNode<E>
{
   // package access members; List can access these directly
   E data; // data for this node
   ListNode<E> nextNode; // reference to the next node in the list

   // constructor creates a ListNode that refers to object
   ListNode(E object)
   {
       this(object, null);
   }

   // constructor creates ListNode that refers to the specified
   // object and to the next ListNode
   ListNode(E object, ListNode<E> node)
   {
      data = object;    
      nextNode = node;  
   } 

   // return reference to data in node
   E getData()
   {
       return data;
   }

   // return reference to next node in list
   ListNode<E> getNext()
   {
       return nextNode;
   }
} 

// class List definition
public class List<E> {
   private ListNode<E> firstNode;
   private ListNode<E> lastNode; 
   private String name; // string like "list" used in printing

   // constructor creates empty List with "list" as the name
   public List()
   {
       this("list");
   }

   // constructor creates an empty List with a name
   public List(String listName)
   {
      name = listName;
      firstNode = lastNode = null;
   } 

   // insert item at front of List
   public void insertAtFront(E insertItem)
   {
      if (isEmpty()) { // firstNode and lastNode refer to same object
         firstNode = lastNode = new ListNode<E>(insertItem);
      } 
      else { // firstNode refers to new node
         firstNode = new ListNode<E>(insertItem, firstNode);
      } 
   } 

   // insert item at end of List
   public void insertAtBack(E insertItem)
   {
      if (isEmpty()) { // firstNode and lastNode refer to same object
         firstNode = lastNode = new ListNode<E>(insertItem);
      } 
      else { // lastNode's nextNode refers to new node
         lastNode = lastNode.nextNode = new ListNode<E>(insertItem);
      } 
   } 

   // remove first node from List
   public E removeFromFront() throws NoSuchElementException
   {
      if (isEmpty()) // throw exception if List is empty
      { 
         throw new NoSuchElementException(name + " is empty");
      }

      E removedItem = firstNode.data; // retrieve data being removed

      // update references firstNode and lastNode 
      if (firstNode == lastNode)
      {
         firstNode = lastNode = null;
      }
      else
      {
         firstNode = firstNode.nextNode;
      }

      return removedItem; // return removed node data
   } 

   // remove last node from List
   public E removeFromBack() throws NoSuchElementException
   {
      if (isEmpty()) // throw exception if List is empty
      { 
         throw new NoSuchElementException(name + " is empty");
      }

      E removedItem = lastNode.data; // retrieve data being removed

      // update references firstNode and lastNode
      if (firstNode == lastNode)
      {
         firstNode = lastNode = null;
      }
      else
      {  // locate new last node
         ListNode<E> current = firstNode;

         // loop while current node does not refer to lastNode
         while (current.nextNode != lastNode)
         {
            current = current.nextNode;
         }
   
         lastNode = current; // current is new lastNode
         current.nextNode = null;
      } 

      return removedItem; // return removed node data
   } 

   // determine whether list is empty; returns true if so
   public boolean isEmpty()
   {
       return firstNode == null;
   }

   // output list contents
   public void print()
   {
      if (isEmpty())
      {
         System.out.printf("Empty %s%n", name);
         return;
      } 

      System.out.printf("The %s is: ", name);
      ListNode<E> current = firstNode;

      // while not at end of list, output current node's data
      while (current != null)
      {
         System.out.printf("%s ", current.data);
         current = current.nextNode;
      } 

      System.out.println();
   } 
}

Stack.java:

import java.util.NoSuchElementException;

public class Stack<T>
{
   private final List<T> stackList;

   // no-argument constructor
   public Stack()
   { 
      stackList = new List<>("stack"); 
   }

   // add object to stack
   public void push(T object)
   { 
      stackList.insertAtFront(object); 
   }

   // remove object from stack
   public T pop() throws NoSuchElementException
   { 
      return stackList.removeFromFront(); 
   }

   // determine if stack is empty
   public boolean isEmpty()
   { 
      return stackList.isEmpty(); 
   }

   // output stack contents
   public void print()
   { 
      stackList.print(); 
   }
}

Once again, thanks for the help and I apologize if there is missing information. I will update as needed with whatever yall need to help me out with this. I just need to write a functional peek method to return the top of the stack to my test class with a main(). I'm not just looking for an answer, I would appreciate an explanation of how and why it works.

There is something I am missing here obviously, and I cannot put my finger on it.

I looked everywhere online including here on StackOverflow, and everyone uses either prebuilt data structures (which we are told to never reinvent the wheel but still need to learn how they work), and I HAVE to use the files that he has included, which are missing methods like size in the List class, which would make my peek method fairly easy to achieve.

The only way I got this to work was to add an instance variable and manipulate the variable in the push and pop methods to always be pointing at the top of the stack. After he said I couldn't do that, I erased everything and screamed lol.

1

There are 1 best solutions below

0
Nuradil Zhanadil uulu On

Stack is not that complicated DS. It follows LIFO method (Last in First out). You can imagine it like a books on top of each other. To be able to take book at the bottom, you will have to take all books starting from top. Thats how stack works.

Here since you already have a class List, I would prefer this class having get method, where you could get Elements by its index. Or in our situation only the first Element, which is Head (firstNode).

// Inside List class
public E getFirst()
{
   return firstNode.data;
}

// Inside stack class
public E peek()
{
    return stackList.getFirst();
}

By this small pieces of code, now you have implemented Stack's peek method