Skip to content

Commit b670e20

Browse files
authored
Add array stack implementation (williamfiset#186)
1 parent 96e3c4e commit b670e20

File tree

5 files changed

+192
-80
lines changed

5 files changed

+192
-80
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.williamfiset.algorithms.datastructures.stack;
2+
3+
import java.util.Arrays;
4+
import java.util.EmptyStackException;
5+
6+
/** @author liujingkun */
7+
public class ArrayStack<T> implements Stack<T> {
8+
private int capacity;
9+
private Object[] data;
10+
private int size;
11+
12+
public ArrayStack() {
13+
capacity = 16;
14+
size = 0;
15+
data = new Object[capacity];
16+
}
17+
18+
@Override
19+
public int size() {
20+
return size;
21+
}
22+
23+
@Override
24+
public boolean isEmpty() {
25+
return size == 0;
26+
}
27+
28+
@Override
29+
public void push(T elem) {
30+
if (size == capacity) {
31+
adjustCap();
32+
}
33+
data[size++] = elem;
34+
}
35+
36+
// adjust the capacity to store more element
37+
private void adjustCap() {
38+
if (capacity == Integer.MAX_VALUE) {
39+
throw new OutOfMemoryError();
40+
}
41+
capacity += capacity;
42+
data = Arrays.copyOf(data, capacity);
43+
}
44+
45+
@Override
46+
@SuppressWarnings("unchecked")
47+
public T pop() {
48+
if (isEmpty()) throw new EmptyStackException();
49+
T elem = (T) data[--size];
50+
data[size] = null;
51+
return elem;
52+
}
53+
54+
@Override
55+
@SuppressWarnings("unchecked")
56+
public T peek() {
57+
if (isEmpty()) throw new EmptyStackException();
58+
return (T) data[size - 1];
59+
}
60+
}

src/main/java/com/williamfiset/algorithms/datastructures/stack/IntStack.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,30 @@ private static void benchMarkTest() {
8383
System.out.println("IntStack Time: " + (end - start) / 1e9);
8484

8585
// ArrayDeque times at around 1.438 seconds
86-
java.util.ArrayDeque<Integer> arrayDeque = new java.util.ArrayDeque<>();
87-
// java.util.ArrayDeque <Integer> arrayDeque = new java.util.ArrayDeque<>(n); // strangely the
86+
// java.util.ArrayDeque<Integer> arrayDeque = new java.util.ArrayDeque<>();
87+
// java.util.Stack<Integer> arrayDeque = new java.util.Stack<>();
88+
java.util.ArrayDeque<Integer> arrayDeque = new java.util.ArrayDeque<>(n); // strangely the
8889
// ArrayQueue is slower when you give it an initial capacity.
8990
start = System.nanoTime();
9091
for (int i = 0; i < n; i++) arrayDeque.push(i);
9192
for (int i = 0; i < n; i++) arrayDeque.pop();
9293
end = System.nanoTime();
9394
System.out.println("ArrayDeque Time: " + (end - start) / 1e9);
95+
96+
Stack<Integer> listStack = new ListStack<>();
97+
98+
start = System.nanoTime();
99+
for (int i = 0; i < n; i++) listStack.push(i);
100+
for (int i = 0; i < n; i++) listStack.pop();
101+
end = System.nanoTime();
102+
System.out.println("ListStack Time: " + (end - start) / 1e9);
103+
104+
Stack<Integer> arrayStack = new ArrayStack<>();
105+
106+
start = System.nanoTime();
107+
for (int i = 0; i < n; i++) arrayStack.push(i);
108+
for (int i = 0; i < n; i++) arrayStack.pop();
109+
end = System.nanoTime();
110+
System.out.println("ArrayStack Time: " + (end - start) / 1e9);
94111
}
95112
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* A linked list implementation of a stack
3+
*
4+
* @author William Fiset, william.alexandre.fiset@gmail.com
5+
*/
6+
package com.williamfiset.algorithms.datastructures.stack;
7+
8+
public class ListStack<T> implements Iterable<T>, Stack<T> {
9+
10+
private java.util.LinkedList<T> list = new java.util.LinkedList<T>();
11+
12+
// Create an empty stack
13+
public ListStack() {}
14+
15+
// Create a Stack with an initial element
16+
public ListStack(T firstElem) {
17+
push(firstElem);
18+
}
19+
20+
// Return the number of elements in the stack
21+
public int size() {
22+
return list.size();
23+
}
24+
25+
// Check if the stack is empty
26+
public boolean isEmpty() {
27+
return size() == 0;
28+
}
29+
30+
// Push an element on the stack
31+
public void push(T elem) {
32+
list.addLast(elem);
33+
}
34+
35+
// Pop an element off the stack
36+
// Throws an error is the stack is empty
37+
public T pop() {
38+
if (isEmpty()) throw new java.util.EmptyStackException();
39+
return list.removeLast();
40+
}
41+
42+
// Peek the top of the stack without removing an element
43+
// Throws an exception if the stack is empty
44+
public T peek() {
45+
if (isEmpty()) throw new java.util.EmptyStackException();
46+
return list.peekLast();
47+
}
48+
49+
// Allow users to iterate through the stack using an iterator
50+
@Override
51+
public java.util.Iterator<T> iterator() {
52+
return list.iterator();
53+
}
54+
}
Lines changed: 11 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,18 @@
1-
/**
2-
* A linked list implementation of a stack
3-
*
4-
* @author William Fiset, william.alexandre.fiset@gmail.com
5-
*/
61
package com.williamfiset.algorithms.datastructures.stack;
72

8-
public class Stack<T> implements Iterable<T> {
3+
/** @author liujingkun */
4+
public interface Stack<T> {
5+
// return the number of elements in the stack
6+
public int size();
97

10-
private java.util.LinkedList<T> list = new java.util.LinkedList<T>();
8+
// return if the stack is empty
9+
public boolean isEmpty();
1110

12-
// Create an empty stack
13-
public Stack() {}
11+
// push the element on the stack
12+
public void push(T elem);
1413

15-
// Create a Stack with an initial element
16-
public Stack(T firstElem) {
17-
push(firstElem);
18-
}
14+
// pop the element off the stack
15+
public T pop();
1916

20-
// Return the number of elements in the stack
21-
public int size() {
22-
return list.size();
23-
}
24-
25-
// Check if the stack is empty
26-
public boolean isEmpty() {
27-
return size() == 0;
28-
}
29-
30-
// Push an element on the stack
31-
public void push(T elem) {
32-
list.addLast(elem);
33-
}
34-
35-
// Pop an element off the stack
36-
// Throws an error is the stack is empty
37-
public T pop() {
38-
if (isEmpty()) throw new java.util.EmptyStackException();
39-
return list.removeLast();
40-
}
41-
42-
// Peek the top of the stack without removing an element
43-
// Throws an exception if the stack is empty
44-
public T peek() {
45-
if (isEmpty()) throw new java.util.EmptyStackException();
46-
return list.peekLast();
47-
}
48-
49-
// Allow users to iterate through the stack using an iterator
50-
@Override
51-
public java.util.Iterator<T> iterator() {
52-
return list.iterator();
53-
}
17+
public T peek();
5418
}
Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,88 @@
11
package com.williamfiset.algorithms.datastructures.stack;
22

3-
import static org.junit.Assert.assertEquals;
4-
import static org.junit.Assert.assertTrue;
3+
import static org.junit.Assert.*;
54

5+
import java.util.ArrayList;
6+
import java.util.List;
67
import org.junit.Before;
78
import org.junit.Test;
9+
import org.junit.function.ThrowingRunnable;
810

911
public class StackTest {
1012

11-
Stack<Integer> stack;
13+
private List<Stack<Integer>> stacks = new ArrayList<>();
1214

1315
@Before
1416
public void setup() {
15-
stack = new Stack<Integer>();
17+
stacks.add(new ListStack<Integer>());
18+
stacks.add(new ArrayStack<Integer>());
1619
}
1720

1821
@Test
1922
public void testEmptyStack() {
20-
assertTrue(stack.isEmpty());
21-
assertEquals(stack.size(), 0);
23+
for (Stack stack : stacks) {
24+
assertTrue(stack.isEmpty());
25+
assertEquals(stack.size(), 0);
26+
}
2227
}
2328

24-
@Test(expected = Exception.class)
29+
@Test
2530
public void testPopOnEmpty() {
26-
stack.pop();
31+
for (Stack stack : stacks) {
32+
assertThrows(Exception.class, stack::pop);
33+
}
2734
}
2835

2936
@Test(expected = Exception.class)
3037
public void testPeekOnEmpty() {
31-
stack.peek();
38+
for (Stack stack : stacks) {
39+
assertThrows(Exception.class, (ThrowingRunnable) stack.peek());
40+
}
3241
}
3342

3443
@Test
3544
public void testPush() {
36-
stack.push(2);
37-
assertEquals(stack.size(), 1);
45+
for (Stack<Integer> stack : stacks) {
46+
stack.push(2);
47+
assertEquals(stack.size(), 1);
48+
}
3849
}
3950

4051
@Test
4152
public void testPeek() {
42-
stack.push(2);
43-
assertTrue(stack.peek() == 2);
44-
assertEquals(stack.size(), 1);
53+
for (Stack<Integer> stack : stacks) {
54+
stack.push(2);
55+
assertEquals(2, (int) (Integer) stack.peek());
56+
assertEquals(stack.size(), 1);
57+
}
4558
}
4659

4760
@Test
4861
public void testPop() {
49-
stack.push(2);
50-
assertTrue(stack.pop() == 2);
51-
assertEquals(stack.size(), 0);
62+
for (Stack<Integer> stack : stacks) {
63+
stack.push(2);
64+
assertEquals(2, (int) stack.pop());
65+
assertEquals(stack.size(), 0);
66+
}
5267
}
5368

5469
@Test
5570
public void testExhaustively() {
56-
assertTrue(stack.isEmpty());
57-
stack.push(1);
58-
assertTrue(!stack.isEmpty());
59-
stack.push(2);
60-
assertEquals(stack.size(), 2);
61-
assertTrue(stack.peek() == 2);
62-
assertEquals(stack.size(), 2);
63-
assertTrue(stack.pop() == 2);
64-
assertEquals(stack.size(), 1);
65-
assertTrue(stack.peek() == 1);
66-
assertEquals(stack.size(), 1);
67-
assertTrue(stack.pop() == 1);
68-
assertEquals(stack.size(), 0);
69-
assertTrue(stack.isEmpty());
71+
for (Stack<Integer> stack : stacks) {
72+
assertTrue(stack.isEmpty());
73+
stack.push(1);
74+
assertFalse(stack.isEmpty());
75+
stack.push(2);
76+
assertEquals(stack.size(), 2);
77+
assertEquals(2, (int) stack.peek());
78+
assertEquals(stack.size(), 2);
79+
assertEquals(2, (int) stack.pop());
80+
assertEquals(stack.size(), 1);
81+
assertEquals(1, (int) stack.peek());
82+
assertEquals(stack.size(), 1);
83+
assertEquals(1, (int) stack.pop());
84+
assertEquals(stack.size(), 0);
85+
assertTrue(stack.isEmpty());
86+
}
7087
}
7188
}

0 commit comments

Comments
 (0)