Introduction to data structures : Implementing a generic Stack in Java

in #programming8 years ago

What is a Stack?

The stack data structure follows the LIFO (Last-in, First-out) principal.
Imagine a stack of plates, when you add a plate to the pile you can only remove
the top plate. This is exactly how a stack works, you pile objects on top of each other,
but you can only access the one at the top.

A stack is very convenient in these situations :

  • Undoing actions (CTRL+Z)
  • Reversing data
  • When we only want to access the last data (Stack of plates)

A stack is characterized with these three methods

  • Push() Adding to the stack.
  • Pop() Removing from the stack.
  • Peek() Peeking at the item on the top of the stack.

We will also make a method to check if the stack is empty

  • isEmpty() returns true if the stack is empty, false otherwise


Source

When should I prefer it over other data structures?

The stack is useful when you only need to access the last data we added in the data structure.
The stack is highly efficient on both adding and removing elements, however you
only have access to the last data you added which makes it limited on other operations.
This makes the stack very useful, but only in specfic scenarios.

Creating a node

We will use the exact same node we used in the linked list tutorial
in order to link data together. I would recommend understanding the linked list first,
because a stack links the nodes the same way the linked list does.

public class Stack<T>
{
    private Node<T> head = null;

    /**
     * The node contains a value of type T
     * and a reference to the next node in the stack.
     */
    private class Node<T>
    {
        public T value;
        public Node<T> nextNode;

        public Node(T value)
        {
            this.value = value;
        }
    }
}

We create a class named Stack that accepts a generic type T. We also
create an inner class called Node that accepts a generic type T. The node
class holds a value of type T and holds a pointer to the next node.

The isEmpty() method

We will start by adding a convenience method boolean isEmpty() and we will
make it public. This method is very simple, it checks if the head contains an element,
if not we know it is empty. The entire code of the empty method is as follows :

public boolean isEmpty()
{
    return head == null;
}

The push() method

The push method allows us to add an element to the stack. We first want to know, if
we are adding the first element, because we will set the head to that node if that is
the case. If we have atleast one element in our stack, we will save a reference to our
head in another variable, set the new head which is the element we just added and set the
next node of that new element to the old head.

public void push(T object)
{
    if(isEmpty())
    {
        head = new Node<>(object);
    }else{
        Node<T> detachedHead = head;
        head = new Node<>(object);
        head.nextNode = detachedHead;
    }
}

The pop() method

The pop method returns the first value of the stack while making the new head the second element.
We first check if the stack is empty, if it is we throw an EmptyStackException().
We simply need save a reference to the head's value, replace the head and return the value.

public T pop()
{
    if(!isEmpty())
    {
        T value = head.value;
        head = head.nextNode;
        return value;
    }else throw new EmptyStackException();
}

The peek() method

Unlike the pop method, the peek method returns the first value of the stack without
removing it. We make sure the stack is not empty before returning the value, if it is empty
we throw an EmptyStackException().

public T peek()
{
    if(!isEmpty())
        return head.value;
    else throw new EmptyStackException();
}

Testing our stack!

Imagine Tom is holding a party and invites Bob, Rick, Michael and Jack.
Tom has a driveway big enough to park four cars, however only one car can go through.
This means the first one to enter is the last one out.

public class Main {

    public static void main(String[] args) {

        String[] names = new String[]{"Bob", "Rick", "Michael", "Jack"};

        Stack<String> stack = new Stack<>();
        for(String name : names)
        {
            stack.push(name);
            System.out.println(name + " parked his car in the driveway!");
        }

        String lastEntered = stack.peek();
        System.out.println("The last car to be parked is " + lastEntered + "'s");

        while (!stack.isEmpty())
        {
            String name = stack.pop();
            System.out.println(name + " removed his car from the driveway");
        }
    }
}

The output of this code should be :

Bob parked his car in the driveway!
Rick parked his car in the driveway!
Michael parked his car in the driveway!
Jack parked his car in the driveway!
The last car to be parked is Jack's
Jack removed his car from the driveway
Michael removed his car from the driveway
Rick removed his car from the driveway
Bob removed his car from the driveway

Jack entered last and is the first one out (LIFO). Bob entered first and is the last
one out.

Conclusion

Thank you for following this tutorial concerning the stack. If you enjoyed this tutorial
please consider following me on Steemit, because I will post more.

Sort:  

Hey @loomy

I got to see this post randomly on Steemit feed. I am happy because we have this chapter in my semester examination after 2 days. Thus your post is definitely going to help me.
Thanks fro that.

Since you too are into Programming, you might like this. Please do share your opinions.
https://steemit.com/art/@premraval010/the-art-of-computer-programming-or-donald-knuth

Coin Marketplace

STEEM 0.13
TRX 0.34
JST 0.036
BTC 107691.96
ETH 4407.15
USDT 1.00
SBD 0.83