Stack Implementation using Linked List in Java

0 49

Stack is a type of linear data structure that follows a partcular order. There are different rules we could implement in a stack, the orders may be LIFO (Last In First Out) or FILO (First In Last Out). We could think of it as a stack of dinner plates, or layers of books and so on. In this article, I will show you how to implement a stack in Java using linked list data structure.

For people who don't know, linked list is also a linear data structure that is made of sequence of nodes connected to each other. A node has two attributes, one is the value storage and the next pointer or the connector to the next node.

Prerequisites

  • You must have some basic fundamentals of Java programming language (basic sintax, OOP) or any other options.

  • Basic understanding of linked list.

  • Basic understanding of the concepts of stack.

Implementation

Before we begin with the implementation, we should know what are the operations we can apply to the stack, here are some common operations:

Push - To add new vlaue at the top of the stack.

Pop - To remove the value at the top of the stack.

Peek - To display the top value of the stack.

Display - To display all the values in the stack.

isFull - To check if the stack is full.

isEmpty - To check if the stack is empty.

We can also add some additional operations like setting the capacity of the stack because linked list is a dynamic data structure, so we must determine the maximum capacity or let the user to input its size.

Creating the Node class

public class Node{
	int data;
	Node next;
	public Node(int data){
		this.data = data;
		next = null;
	}
}

I created the Node class as public to get access if I use it in the stack class. after that, I declared the attributes data and next pointer. And lastly I created the Node constructor that accepts an argument data to store in the data attribute.

Creating the Stack class

public class Stack {
    private Node top;
    static int capacity;
    int size;

    public Stack(){
        top = null;
        capacity = 0;
        size = 0;
    }
}

After creating the stack class, I added the top, capacity and size attributes. The top will be used for storing the top node as it acts like a marker so the data will not be lost. Then I created the constructor to set their default values.

Creating the Push operation

public void Push(int data){
	if(size < capacity){
		Node newNode = new Node(data);
		if(top == null){
			top = newNode;
		} else {
			newNode.next = top;
			top = newNode;
		}
		size++;
	} else {
		System.out.println("\nStack Overflow.");
		isFull();
	}
}

I implemented the push operation by checking if the current size of the stack is equal to the capacity, if they're equal, the stack will no longer accept any values. However, if the stack has available spaces, it will add to the top and the size will increment by 1.

The insert algorithm is by check if the top is null, the node will be assigned to the top, else, the newNode next pointer will be equal to the node which top assigned to. Then the top node will be assigned to the newNode.

Creating the Pop operation

public void Pop(){
	if(size != 0){
		Node temp = top;
		top = top.next;
		temp = null;
		size--;
	} else {
		System.out.println("\nStack Underflow");
		isEmpty();
	}
}

The Pop operation checks if the size is not equals to 0, that just means that it is not empty. Then if the condition has met, a new node temp is instantiated and assigned to the top node. The top will move to the next node and finally, temp will be deleted by assigning it to null value. However, if the size is 0, then it will display as "Stack Underflow" and it will call the isEmpty() method which will be discuss later on.

Creating the Peek operation

public void Peek(){
	if(top == null){
		isEmpty();
	} else {
		System.out.println(top.data);
	}
}

Peek operation is pretty simple, it just displays the top most value. First, is by checking the top if it's null, then the isEmpty() method will be executed. Else, it will print the top value.

Creating the Display operation

public void Display(){
	if(top == null){
		isEmpty();
	} else {
		Node temp = top;
		while(temp != null){
			System.out.println(temp.data);
			temp = temp.next;
		}
	}
}

Display and Peek operations are almost the same. Their only difference is Display show all the stack values while the other one is the top most value. If the top is equals to null, then isEmpty will he executed. Else, new node temp will be assigned to the top node, then it will traverse the linked list at the same time, the values will be printed to the console until temp reach null value.

Creating the isFull operation

public void isFull(){
	if(size == capacity){
		System.out.println("The stack is full.");
	} else {
		System.out.println("The stack isn't full.");
	}
}

This operation check if the stack is full or not, by confirming if the size is equals to capacity.

Creating the isEmpty operation

public void isEmpty(){
	if(top == null){
		System.out.println("The stack is empty."); 
	} else {
		System.out.println("The stack isn't empty.");
	}
}

As you noticed, isEmtpy and isFull have counter purpose. What I mean is they are completely opposite operations, for further explanation, isEmpty is more concerned about the stack being empty while isFull is more concerned if the stack overflows. So isEmtpy works by checking if the top is null, then is will display "The stack is empty."

Creating some additional features

public void setCapacity(int size){
	this.capacity = size;
}
	
public int getCapacity(){
	return capacity;
}

I created a setter and getter for the capacity so the ser can assign a maximum size to the stack.

You can add more features if you want to, it is optional but it's up to you.

The main program

class Main {
  	public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
		Stack stack = new Stack(); //Instantiation.
        int max = scanner.nextInt();
		stack.setCapacity(4); //Setting the maximum capacity of the stack.
		stack.Push(1); //Pushing new value to the stack.
		stack.Push(2);
		stack.Push(3);
		stack.Push(4);
		stack.Pop();
		stack.Push(6);
		stack.Display(); //Displaying all the value from the stack without popping it.
		stack.Push(5); //Stack Overflow.
		stack.Pop(); //Popping top value of the stack.
		stack.isFull(); //Checking if the stack is full.
		stack.isEmpty(); //Checking if the stack is empty.
		stack.Peek(); //Displaying the top value of the stack.
		System.out.println(stack.getCapacity());
 	}
}

Java doesn't support pointers unlike other older languages such as C and C++. It supports referencing but that's just it, but because of OOP (Object Oriented Programming) it is easier to program it in java. Although, I have some concepts that I haven't clarify, I hope this would help you understand more on how it works.

3
$ 0.14
$ 0.09 from @TheRandomRewarder
$ 0.05 from @Ceddy-lim

Comments