Skip to content

Commit ab9a552

Browse files
authored
Enhance docs, remove main, add tests in NodeStack (#6017)
1 parent 1e50706 commit ab9a552

File tree

3 files changed

+141
-107
lines changed

3 files changed

+141
-107
lines changed

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,7 @@
866866
* [QueueByTwoStacksTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/queues/QueueByTwoStacksTest.java)
867867
* [QueueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/queues/QueueTest.java)
868868
* stacks
869+
* [NodeStackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/NodeStackTest.java)
869870
* [StackArrayListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackArrayListTest.java)
870871
* [StackArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackArrayTest.java)
871872
* [StackOfLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackOfLinkedListTest.java)
Lines changed: 55 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,161 +1,109 @@
11
package com.thealgorithms.datastructures.stacks;
22

33
/**
4-
* Implementation of a stack using nodes. Unlimited size, no arraylist.
4+
* A stack implementation using linked nodes, supporting unlimited size without an ArrayList.
55
*
6-
* @author Kyler Smith, 2017
6+
* <p>Each node in the stack contains data of generic type {@code Item}, along with references
7+
* to the next and previous nodes, supporting typical stack operations.
8+
*
9+
* <p>The stack follows a Last-In-First-Out (LIFO) order where elements added last are
10+
* removed first. Supported operations include push, pop, and peek.
11+
*
12+
* @param <Item> the type of elements held in this stack
713
*/
814
public class NodeStack<Item> {
915

1016
/**
11-
* Entry point for the program.
17+
* Node class representing each element in the stack.
1218
*/
13-
public static void main(String[] args) {
14-
NodeStack<Integer> stack = new NodeStack<Integer>();
15-
16-
stack.push(3);
17-
stack.push(4);
18-
stack.push(5);
19-
System.out.println("Testing :");
20-
stack.print(); // prints : 5 4 3
19+
private class Node {
20+
Item data;
21+
Node previous;
2122

22-
Integer x = stack.pop(); // x = 5
23-
stack.push(1);
24-
stack.push(8);
25-
Integer y = stack.peek(); // y = 8
26-
System.out.println("Testing :");
27-
stack.print(); // prints : 8 1 4 3
28-
29-
System.out.println("Testing :");
30-
System.out.println("x : " + x);
31-
System.out.println("y : " + y);
23+
Node(Item data) {
24+
this.data = data;
25+
this.previous = null;
26+
}
3227
}
3328

34-
/**
35-
* Information each node should contain.
36-
*
37-
* @value data : information of the value in the node
38-
* @value head : the head of the stack
39-
* @value next : the next value from this node
40-
* @value previous : the last value from this node
41-
* @value size : size of the stack
42-
*/
43-
private Item data;
44-
45-
private static NodeStack<?> head;
46-
private NodeStack<?> previous;
47-
private static int size = 0;
29+
private Node head; // Top node in the stack
30+
private int size; // Number of elements in the stack
4831

4932
/**
50-
* Constructors for the NodeStack.
33+
* Constructs an empty NodeStack.
5134
*/
5235
public NodeStack() {
53-
}
54-
55-
private NodeStack(Item item) {
56-
this.data = item;
36+
head = null;
37+
size = 0;
5738
}
5839

5940
/**
60-
* Put a value onto the stack.
41+
* Pushes an item onto the stack.
6142
*
62-
* @param item : value to be put on the stack.
43+
* @param item the item to be pushed onto the stack
6344
*/
6445
public void push(Item item) {
65-
NodeStack<Item> newNs = new NodeStack<Item>(item);
66-
67-
if (this.isEmpty()) {
68-
NodeStack.setHead(new NodeStack<>(item));
69-
newNs.setNext(null);
70-
newNs.setPrevious(null);
71-
} else {
72-
newNs.setPrevious(NodeStack.head);
73-
NodeStack.head.setNext(newNs);
74-
NodeStack.setHead(newNs);
75-
}
76-
77-
NodeStack.setSize(NodeStack.getSize() + 1);
46+
Node newNode = new Node(item);
47+
newNode.previous = head;
48+
head = newNode;
49+
size++;
7850
}
7951

8052
/**
81-
* Value to be taken off the stack.
53+
* Removes and returns the item at the top of the stack.
8254
*
83-
* @return item : value that is returned.
55+
* @return the item at the top of the stack, or {@code null} if the stack is empty
56+
* @throws IllegalStateException if the stack is empty
8457
*/
8558
public Item pop() {
86-
Item item = (Item) NodeStack.head.getData();
87-
88-
NodeStack.setHead(NodeStack.head.getPrevious());
89-
NodeStack.head.setNext(null);
90-
91-
NodeStack.setSize(NodeStack.getSize() - 1);
92-
93-
return item;
59+
if (isEmpty()) {
60+
throw new IllegalStateException("Cannot pop from an empty stack.");
61+
}
62+
Item data = head.data;
63+
head = head.previous;
64+
size--;
65+
return data;
9466
}
9567

9668
/**
97-
* Value that is next to be taken off the stack.
69+
* Returns the item at the top of the stack without removing it.
9870
*
99-
* @return item : the next value that would be popped off the stack.
71+
* @return the item at the top of the stack, or {@code null} if the stack is empty
72+
* @throws IllegalStateException if the stack is empty
10073
*/
10174
public Item peek() {
102-
return (Item) NodeStack.head.getData();
75+
if (isEmpty()) {
76+
throw new IllegalStateException("Cannot peek from an empty stack.");
77+
}
78+
return head.data;
10379
}
10480

10581
/**
106-
* If the stack is empty or there is a value in.
82+
* Checks whether the stack is empty.
10783
*
108-
* @return boolean : whether or not the stack has anything in it.
84+
* @return {@code true} if the stack has no elements, {@code false} otherwise
10985
*/
11086
public boolean isEmpty() {
111-
return NodeStack.getSize() == 0;
87+
return head == null;
11288
}
11389

11490
/**
115-
* Returns the size of the stack.
91+
* Returns the number of elements currently in the stack.
11692
*
117-
* @return int : number of values in the stack.
93+
* @return the size of the stack
11894
*/
11995
public int size() {
120-
return NodeStack.getSize();
96+
return size;
12197
}
12298

12399
/**
124-
* Print the contents of the stack in the following format.
125-
*
126-
* <p>
127-
* x <- head (next out) y z <- tail (first in) . . .
100+
* Prints the contents of the stack from top to bottom.
128101
*/
129102
public void print() {
130-
for (NodeStack<?> n = NodeStack.head; n != null; n = n.previous) {
131-
System.out.println(n.getData().toString());
103+
Node current = head;
104+
while (current != null) {
105+
System.out.println(current.data);
106+
current = current.previous;
132107
}
133108
}
134-
135-
private static void setHead(NodeStack<?> ns) {
136-
NodeStack.head = ns;
137-
}
138-
139-
private void setNext(NodeStack<?> next) {
140-
}
141-
142-
private NodeStack<?> getPrevious() {
143-
return previous;
144-
}
145-
146-
private void setPrevious(NodeStack<?> previous) {
147-
this.previous = previous;
148-
}
149-
150-
private static int getSize() {
151-
return size;
152-
}
153-
154-
private static void setSize(int size) {
155-
NodeStack.size = size;
156-
}
157-
158-
private Item getData() {
159-
return this.data;
160-
}
161109
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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.assertThrows;
6+
import static org.junit.jupiter.api.Assertions.assertTrue;
7+
8+
import org.junit.jupiter.api.Test;
9+
10+
class NodeStackTest {
11+
12+
@Test
13+
void testPush() {
14+
NodeStack<Integer> stack = new NodeStack<>();
15+
stack.push(10);
16+
stack.push(20);
17+
assertEquals(20, stack.peek(), "Top element should be 20 after pushing 10 and 20.");
18+
}
19+
20+
@Test
21+
void testPop() {
22+
NodeStack<String> stack = new NodeStack<>();
23+
stack.push("First");
24+
stack.push("Second");
25+
assertEquals("Second", stack.pop(), "Pop should return 'Second', the last pushed element.");
26+
assertEquals("First", stack.pop(), "Pop should return 'First' after 'Second' is removed.");
27+
}
28+
29+
@Test
30+
void testPopOnEmptyStack() {
31+
NodeStack<Double> stack = new NodeStack<>();
32+
assertThrows(IllegalStateException.class, stack::pop, "Popping an empty stack should throw IllegalStateException.");
33+
}
34+
35+
@Test
36+
void testPeek() {
37+
NodeStack<Integer> stack = new NodeStack<>();
38+
stack.push(5);
39+
stack.push(15);
40+
assertEquals(15, stack.peek(), "Peek should return 15, the top element.");
41+
stack.pop();
42+
assertEquals(5, stack.peek(), "Peek should return 5 after 15 is popped.");
43+
}
44+
45+
@Test
46+
void testPeekOnEmptyStack() {
47+
NodeStack<String> stack = new NodeStack<>();
48+
assertThrows(IllegalStateException.class, stack::peek, "Peeking an empty stack should throw IllegalStateException.");
49+
}
50+
51+
@Test
52+
void testIsEmpty() {
53+
NodeStack<Character> stack = new NodeStack<>();
54+
assertTrue(stack.isEmpty(), "Newly initialized stack should be empty.");
55+
stack.push('A');
56+
assertFalse(stack.isEmpty(), "Stack should not be empty after a push operation.");
57+
stack.pop();
58+
assertTrue(stack.isEmpty(), "Stack should be empty after popping the only element.");
59+
}
60+
61+
@Test
62+
void testSize() {
63+
NodeStack<Integer> stack = new NodeStack<>();
64+
assertEquals(0, stack.size(), "Size of empty stack should be 0.");
65+
stack.push(3);
66+
stack.push(6);
67+
assertEquals(2, stack.size(), "Size should be 2 after pushing two elements.");
68+
stack.pop();
69+
assertEquals(1, stack.size(), "Size should be 1 after popping one element.");
70+
stack.pop();
71+
assertEquals(0, stack.size(), "Size should be 0 after popping all elements.");
72+
}
73+
74+
@Test
75+
void testPrint() {
76+
NodeStack<Integer> stack = new NodeStack<>();
77+
stack.push(1);
78+
stack.push(2);
79+
stack.push(3);
80+
81+
// Output verification would ideally be handled through a different means
82+
// but you can print as a basic check to confirm method runs without errors.
83+
stack.print();
84+
}
85+
}

0 commit comments

Comments
 (0)