Skip to content

Commit b95632c

Browse files
authored
Merge branch 'master' into node_stack_improve
2 parents 99fde04 + 6684a69 commit b95632c

File tree

4 files changed

+165
-122
lines changed

4 files changed

+165
-122
lines changed

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,7 @@
860860
* [NodeStackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/NodeStackTest.java)
861861
* [StackArrayListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackArrayListTest.java)
862862
* [StackArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackArrayTest.java)
863+
* [StackOfLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackOfLinkedListTest.java)
863864
* trees
864865
* [BinaryTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BinaryTreeTest.java)
865866
* [BoundaryTraversalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BoundaryTraversalTest.java)

src/main/java/com/thealgorithms/datastructures/stacks/StackOfLinkedList.java

Lines changed: 43 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,20 @@
33
import java.util.NoSuchElementException;
44

55
/**
6-
* @author Varun Upadhyay (https://github.com/varunu28)
6+
* A stack implementation using a singly linked list.
7+
*
8+
* <p>This class provides methods to push, pop, and peek elements in a Last-In-First-Out (LIFO) manner.
9+
* It keeps track of the number of elements in the stack and allows checking if the stack is empty.
10+
*
11+
* <p>This implementation does not allow null elements to be pushed onto the stack.
712
*/
8-
// An implementation of a Stack using a Linked List
913
final class StackOfLinkedList {
1014
private StackOfLinkedList() {
1115
}
12-
13-
public static void main(String[] args) {
14-
LinkedListStack stack = new LinkedListStack();
15-
stack.push(1);
16-
stack.push(2);
17-
stack.push(3);
18-
stack.push(4);
19-
stack.push(5);
20-
21-
System.out.println(stack);
22-
23-
System.out.println("Size of stack currently is: " + stack.getSize());
24-
25-
assert stack.pop() == 5;
26-
assert stack.pop() == 4;
27-
28-
System.out.println("Top element of stack currently is: " + stack.peek());
29-
}
3016
}
3117

32-
// A node class
18+
// A node class for the linked list
3319
class Node {
34-
3520
public int data;
3621
public Node next;
3722

@@ -42,36 +27,35 @@ class Node {
4227
}
4328

4429
/**
45-
* A class which implements a stack using a linked list
30+
* A class that implements a stack using a linked list.
4631
*
47-
* <p>
48-
* Contains all the stack methods : push, pop, printStack, isEmpty
32+
* <p>This stack supports basic operations:
33+
* <ul>
34+
* <li>push: Adds an element to the top of the stack</li>
35+
* <li>pop: Removes and returns the top element of the stack</li>
36+
* <li>peek: Returns the top element without removing it</li>
37+
* <li>isEmpty: Checks if the stack is empty</li>
38+
* <li>getSize: Returns the current size of the stack</li>
39+
* </ul>
4940
*/
5041
class LinkedListStack {
5142

52-
/**
53-
* Top of stack
54-
*/
55-
Node head;
43+
private Node head; // Top of the stack
44+
private int size; // Number of elements in the stack
5645

5746
/**
58-
* Size of stack
59-
*/
60-
private int size;
61-
62-
/**
63-
* Init properties
47+
* Initializes an empty stack.
6448
*/
6549
LinkedListStack() {
6650
head = null;
6751
size = 0;
6852
}
6953

7054
/**
71-
* Add element at top
55+
* Adds an element to the top of the stack.
7256
*
73-
* @param x to be added
74-
* @return <tt>true</tt> if add successfully
57+
* @param x the element to be added
58+
* @return <tt>true</tt> if the element is added successfully
7559
*/
7660
public boolean push(int x) {
7761
Node newNode = new Node(x);
@@ -82,10 +66,10 @@ public boolean push(int x) {
8266
}
8367

8468
/**
85-
* Pop element at top of stack
69+
* Removes and returns the top element of the stack.
8670
*
87-
* @return element at top of stack
88-
* @throws NoSuchElementException if stack is empty
71+
* @return the element at the top of the stack
72+
* @throws NoSuchElementException if the stack is empty
8973
*/
9074
public int pop() {
9175
if (size == 0) {
@@ -94,20 +78,20 @@ public int pop() {
9478
Node destroy = head;
9579
head = head.next;
9680
int retValue = destroy.data;
97-
destroy = null; // clear to let GC do it's work
81+
destroy = null; // Help garbage collection
9882
size--;
9983
return retValue;
10084
}
10185

10286
/**
103-
* Peek element at top of stack
87+
* Returns the top element of the stack without removing it.
10488
*
105-
* @return element at top of stack
106-
* @throws NoSuchElementException if stack is empty
89+
* @return the element at the top of the stack
90+
* @throws NoSuchElementException if the stack is empty
10791
*/
10892
public int peek() {
10993
if (size == 0) {
110-
throw new NoSuchElementException("Empty stack. Nothing to pop");
94+
throw new NoSuchElementException("Empty stack. Nothing to peek");
11195
}
11296
return head.data;
11397
}
@@ -120,24 +104,32 @@ public String toString() {
120104
builder.append(cur.data).append("->");
121105
cur = cur.next;
122106
}
123-
return builder.replace(builder.length() - 2, builder.length(), "").toString();
107+
return builder.replace(builder.length() - 2, builder.length(), "").toString(); // Remove the last "->"
124108
}
125109

126110
/**
127-
* Check if stack is empty
111+
* Checks if the stack is empty.
128112
*
129-
* @return <tt>true</tt> if stack is empty, otherwise <tt>false</tt>
113+
* @return <tt>true</tt> if the stack is empty, <tt>false</tt> otherwise
130114
*/
131115
public boolean isEmpty() {
132116
return size == 0;
133117
}
134118

135119
/**
136-
* Return size of stack
120+
* Returns the current size of the stack.
137121
*
138-
* @return size of stack
122+
* @return the number of elements in the stack
139123
*/
140124
public int getSize() {
141125
return size;
142126
}
127+
128+
/**
129+
* Removes all elements from the stack.
130+
*/
131+
public void makeEmpty() {
132+
head = null;
133+
size = 0;
134+
}
143135
}

src/test/java/com/thealgorithms/datastructures/stacks/LinkedListStackTest.java

Lines changed: 0 additions & 71 deletions
This file was deleted.
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package com.thealgorithms.datastructures.stacks;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertFalse;
5+
import static org.junit.jupiter.api.Assertions.assertTrue;
6+
7+
import java.util.NoSuchElementException;
8+
import org.junit.jupiter.api.BeforeEach;
9+
import org.junit.jupiter.api.Test;
10+
11+
public class StackOfLinkedListTest {
12+
13+
private LinkedListStack stack;
14+
15+
@BeforeEach
16+
public void setUp() {
17+
stack = new LinkedListStack();
18+
}
19+
20+
@Test
21+
public void testPushAndPeek() {
22+
stack.push(1);
23+
stack.push(2);
24+
stack.push(3);
25+
26+
assertEquals(3, stack.peek(), "Peek should return the last pushed value");
27+
assertEquals(3, stack.getSize(), "Size should reflect the number of elements");
28+
}
29+
30+
@Test
31+
public void testPop() {
32+
stack.push(1);
33+
stack.push(2);
34+
stack.push(3);
35+
36+
assertEquals(3, stack.pop(), "Pop should return the last pushed value");
37+
assertEquals(2, stack.pop(), "Pop should return the next last pushed value");
38+
assertEquals(1, stack.pop(), "Pop should return the first pushed value");
39+
assertTrue(stack.isEmpty(), "Stack should be empty after popping all elements");
40+
}
41+
42+
@Test
43+
public void testPopEmptyStack() {
44+
org.junit.jupiter.api.Assertions.assertThrows(NoSuchElementException.class, () -> stack.pop(), "Popping from an empty stack should throw NoSuchElementException");
45+
}
46+
47+
@Test
48+
public void testPeekEmptyStack() {
49+
org.junit.jupiter.api.Assertions.assertThrows(NoSuchElementException.class, () -> stack.peek(), "Peeking into an empty stack should throw NoSuchElementException");
50+
}
51+
52+
@Test
53+
public void testIsEmpty() {
54+
assertTrue(stack.isEmpty(), "Newly created stack should be empty");
55+
56+
stack.push(1);
57+
assertFalse(stack.isEmpty(), "Stack should not be empty after pushing an element");
58+
59+
stack.pop();
60+
assertTrue(stack.isEmpty(), "Stack should be empty after popping the only element");
61+
}
62+
63+
@Test
64+
public void testToString() {
65+
stack.push(1);
66+
stack.push(2);
67+
stack.push(3);
68+
69+
assertEquals("3->2->1", stack.toString(), "String representation of stack should match the expected format");
70+
}
71+
72+
@Test
73+
public void testMultiplePushesAndPops() {
74+
stack.push(5);
75+
stack.push(10);
76+
stack.push(15);
77+
78+
assertEquals(15, stack.pop(), "Pop should return the last pushed value");
79+
assertEquals(10, stack.peek(), "Peek should return the new top value after popping");
80+
assertEquals(10, stack.pop(), "Pop should return the next last pushed value");
81+
assertEquals(5, stack.pop(), "Pop should return the first pushed value");
82+
assertTrue(stack.isEmpty(), "Stack should be empty after popping all elements");
83+
}
84+
85+
@Test
86+
public void testGetSize() {
87+
assertEquals(0, stack.getSize(), "Size of an empty stack should be zero");
88+
stack.push(1);
89+
stack.push(2);
90+
assertEquals(2, stack.getSize(), "Size should reflect the number of elements");
91+
stack.pop();
92+
assertEquals(1, stack.getSize(), "Size should decrease with each pop");
93+
}
94+
95+
@Test
96+
public void testSizeAfterClearingStack() {
97+
stack.push(1);
98+
stack.push(2);
99+
stack.push(3);
100+
101+
// Manually clear the stack
102+
while (!stack.isEmpty()) {
103+
stack.pop();
104+
}
105+
assertTrue(stack.isEmpty(), "Stack should be empty after clearing");
106+
assertEquals(0, stack.getSize(), "Size should be zero after clearing the stack");
107+
}
108+
109+
@Test
110+
public void testSequentialPushAndPop() {
111+
for (int i = 1; i <= 100; i++) {
112+
stack.push(i);
113+
}
114+
assertEquals(100, stack.getSize(), "Size should be 100 after pushing 100 elements");
115+
116+
for (int i = 100; i >= 1; i--) {
117+
assertEquals(i, stack.pop(), "Popping should return values in LIFO order");
118+
}
119+
assertTrue(stack.isEmpty(), "Stack should be empty after popping all elements");
120+
}
121+
}

0 commit comments

Comments
 (0)