ma'am audrey's lessons

ITC 120 › Prelim › Stacks

Linear data structures · Lesson 3 of 4

Stacks

This lesson teaches:Data structure

The newest item leaves first, like the top plate on a pile.

By the end, you can:

  1. explain the last-in, first-out (LIFO) rule and name places where it fits;
  2. trace push, pop, and peek in a table, writing the stack from bottom to top and the value each call returns;
  3. say what each ArrayStack method changes in data and top;
  4. explain underflow and overflow, and how the code guards against them;
  5. trace a program that uses Java's own Stack<Integer>, and explain what the <Integer> means.

You need: the Arrays and Linked lists lessons (for classes, objects, and nodes).

Part 1 · The big idea

A pile with one open end

After a handaan, the clean plates go on one pile. You put each washed plate on the top, and when someone needs a plate, they take the top one. The plate that went in last comes out first.

Clean plates after a handaanbottom: first plate intoppushput a plate on toppoptake the top plateYou never pull a plate from the middle or the bottom.
Plates go on and come off at the top only. The bottom plate went in first and will come out last.

Stack

A stack is a linear data structure (its items form one line) where items are added and removed at one end only, called the top. It follows the LIFO rule: last in, first out. The item added most recently is the first one removed.

Here is the definition as a picture. Four items went in, one after another:

A, B, C, D were pushed in that orderpushpopopen endAin: 1stout: 4thBin: 2ndout: 3rdCin: 3rdout: 2ndDin: 4thtopout: 1stclosed bottom: nothing goes in or out hereLast in (D) is the first out.
The items form one line, from the bottom to the top. Only the top end is open, so every push and every pop happens there. Read the two sides: A went in first but comes out last; D went in last and comes out first. That is LIFO.

What makes something a stack is the rule "only touch the top," not what holds the items. The plates could sit on a table or a shelf; it is still a stack as long as you only add and take at the top. (In Part 4, a stack keeps its items in an array.) Describing something only by what you can do with it has a name, abstract data type; you will meet it in the Sets lesson.

Why follow such a strict rule? Many tasks only ever need the newest item (you will see some below). The rule keeps their order safe: nothing can be pulled from the middle and mix things up.

Here are the words that come with a stack:

WordMeaningWith the plates
topthe end where items enter and leavethe plate on top of the pile
push(x)add x on the topput a clean plate on the pile
pop()remove the top item and return ittake the top plate
peek()return the top item, but keep it therelook at the top plate without taking it
size()how many items the stack holdscount the plates
isEmpty()true when there are no itemsno plates left
isFull()true when a fixed-size stack has no roomthe pile reaches the shelf above

These names are conventions: ordinary method names that a programmer writes, not Java keywords. A different class could call them something else.

Underflow and overflow

Underflow: popping or peeking when the stack is empty (no plates left). Overflow: pushing onto a fixed-size stack that is already full (the shelf has no room).

Underflow: the stack is emptyno plates leftpop()Nothingto take!In code: pop() or peek() when top == -1Overflow: the stack is fullpush(x)No room!the shelf has afixed sizeIn code: push(x) when top == data.length - 1
Both are mistakes in when the program calls a method, not problems with the data. In Part 4, each method checks for them first. Overflow can only happen when the storage has a fixed size, like an array.

Where you see LIFO

Here are three everyday places where the newest item comes out first:

UndoEach change is pushed. Undo pops the newest one.typed "Hello"made it bolddeleted a lineUndobrings backthe deleted lineThe Back buttonEach page you open is pushed. Back pops it.search resultsDOrSU websiteITC 120 pageStacks lessonBackYou are backon ITC 120 pageReversing a wordPush the letters of MATI, then pop them all.M A T Ipush M, A, T, IMATII T A Mpop 4 timesreversed!
In each one, the orange item went in last, so it is the first to come out.

Two more uses, which you will meet in later lessons:

UseHow LIFO fits
Method calls in JavaJava keeps a stack of calls. A call is pushed when a method starts and popped when it finishes. You will see this in the Recursion lesson.
Depth-first searchA stack remembers the path back. You will use it in the DFS lesson.

Undo and Back are illustrations of the rule, not a description of how any particular app is programmed.

Part 2 · Try it

Stack lab

Push three values, then pop them. In which order do they come out? Then try peek: what changes, and what does not?

Stack lab

Type a value, then push, pop, or peek. Every action is written in the log, like a trace table. Try popping an empty stack, or pushing a sixth value.

Stack (LIFO · capacity 5)

OperationStack (bottom → top)Returned

Part 3 · Tracing

Tracing a stack in a table

A trace table shows the stack after every call. This is also the format for exams and coding exercises: one row per call, the stack written bottom → top with commas, and the value the call returns (— if it returns nothing). The stack starts empty, and each row acts on the result of the row before it:

CallStack after (bottom → top)ReturnedsizeWhat happens
push(10)10—110 goes on; it is the top.
push(20)10, 20—220 goes above 10; 20 is the top.
peek()10, 20202Reads the top. Nothing changes.
push(30)10, 20, 30—330 is the new top.
pop()10, 20302Removes 30; 20 is the top again.
pop()10201Removes 20; only 10 is left.

Exam traps

  1. Write the stack bottom → top. The newest item is written last (on the right), not first. So "10, 20, 30" means 30 is on top, like D in .
  2. A call removes even when nothing prints it. A line like s.pop(); still removes the top item. Its value is returned and simply not used, so write it in the Returned column anyway.
  3. peek() changes nothing. Copy the stack from the row above, and write the top value as Returned.

Part 4 · Java

A stack in Java, using an array

Array and index (from the Arrays lesson)

An array is a fixed number of cells side by side, all holding the same type. Each cell has an index, its position number, starting at 0. An array's length never changes, so the last index is length - 1.

Class and object (from the Linked lists lesson)

A class is a blueprint; an object is one real thing made from it with new ( ). A Node object only held data. An ArrayStack object holds data in its fields (data and top) and has methods (push, pop, …) that work on that data.

Java has no class called ArrayStack. It is our own class, written in this lesson; the name just means "a stack that keeps its items in an array." Inside, it is an ordinary array plus one number, top, and the stack rule:

An ordinary array: any cell4091220304You may read or change any index, like data[3].ArrayStack: the same array + topturned up as a column: index 0 at the bottom4091220304push puts it heretop = 2:pop and peekhands off:no reaching intothe middleSame cells. The rule decides what you may do.
Top: an ordinary array lets you use any index. Bottom: the same five cells inside ArrayStack, drawn as a column. 4, 9, 2 are the stack, and top is 2, the index of the top item. The next push goes into cell 3. Cells 0 and 1 are still there, but the stack's methods only ever use the top.

This also makes a stack fast. Adding or removing at the top never shifts other items (as inserting into the middle of an array does), so push and pop take the same few steps however big the stack gets.

The class ArrayStack keeps its items in an array called data. The field top is the index of the top item. A new stack has top = -1, meaning "no top item yet." The -1 is only an index; it is never returned as data. Why not start at 0? top = 0 would mean "the top item is in cell 0," so the stack would already hold one item.

 1class ArrayStack {
 2  int[] data;    // cells that hold the stack items
 3  int top;       // index of the top item; -1 means empty
 4
 5  ArrayStack(int capacity) {
 6    data = new int[capacity];
 7    top = -1;
 8  }
 9  boolean isEmpty() {
10    return top == -1;
11  }
12  boolean isFull() {
13    return top == data.length - 1;
14  }
15  int size() {
16    return top + 1;
17  }
18  // ... push, pop, and peek below
19}

Boolean method

A boolean method returns true or false. return top == -1; returns true exactly when top equals -1.

The three checks all come from the meaning of top:

MethodReturnsWhy
isEmpty()top == -1no top item yet
isFull()top == data.length - 1the top item is in the last cell
size()top + 1indexes start at 0, so top 1 means 2 items

Exception and throw

An exception is an error Java reports while the program is running; if nothing handles it, the program stops. A method can report one itself when it cannot do its job: the throw statement stops the method at once with an exception object. IllegalStateException is Java's standard exception for "you asked at the wrong time," such as popping an empty stack. When the program stops, Java prints the exception's name and message.

To use a stack, a program makes one object with new, then calls its methods with a dot:

ArrayStack s = new ArrayStack(3);s.push(4);the object s (an ArrayStack)fields (its data):data400102top = 0(was -1 before the push)methods (its jobs):push()pop()peek()size()s.push(4): go to the object s, and runits push method with 4. Here the dotmeans "this object's".
The object s has its own fields and its own methods. s.push(4) runs the push method of this stack, so only s changes.

Read s.push(4); aloud as "stack s, push 4." If a program made two stacks, s and t, then t.push(4) would change only t: each object has its own data and top.

Now push, pop, and peek. Each one first checks for overflow or underflow, then does its job. Follow them on a new stack made with new ArrayStack(3). The array is drawn as a column, with index 0 at the bottom, so the top is really on top:

Walkthrough: push(4), push(9), pop(), peek(), then overflow

Use Next to go step by step, or tap a line to jump to it.

dataindex000102-1top= -1stack (bottom → top): empty

value = 4top = -1

The stack was just made with new ArrayStack(3), so top is -1: empty. The three cells hold Java's default 0, but they are all above top (dashed), so none of them is part of the stack. Now s.push(4) runs.

Step 1 of 14
 1void push(int value) { 2  if (isFull()) { 3    throw new IllegalStateException("Stack overflow: full."); 4  } 5  top++;                 // 1. move top up one cell 6  data[top] = value;     // 2. store the value there 7} 8 9int pop() {10  if (isEmpty()) {11    throw new IllegalStateException("Stack underflow: empty.");12  }13  int value = data[top]; // 1. save the top value14  top--;                 // 2. move top down one cell15  return value;16}1718int peek() {19  if (isEmpty()) {20    throw new IllegalStateException("Stack underflow: empty.");21  }22  return data[top];      // look only; top does not change23}

What each method changes

push moves top up one cell, then stores the value there. pop saves the value at top, moves top down, and returns the saved value. peek changes nothing: it returns data[top] and leaves top alone.

Why not return -1 when the stack is empty?

-1 could be real data: a stack of temperatures might hold -1. Throwing an exception makes the mistake impossible to miss. The rule: check isEmpty() before popping or peeking, and isFull() before pushing onto a fixed-size array.

The whole program

Here is everything in one runnable file. main does the same calls as the walkthrough, except the last push(8). To see the overflow exception, add s.push(8); at the end of main.

 1public class Main {
 2  public static void main(String[] args) {
 3    ArrayStack s = new ArrayStack(3);
 4    s.push(4);
 5    s.push(9);
 6    System.out.println(s.pop());     // 9
 7    System.out.println(s.peek());    // 4
 8    s.push(2);
 9    s.push(7);
10    System.out.println(s.size());    // 3
11    System.out.println(s.isFull());  // true
12  }
13}
14
15class ArrayStack {
16  int[] data;    // cells that hold the stack items
17  int top;       // index of the top item; -1 means empty
18
19  ArrayStack(int capacity) {
20    data = new int[capacity];
21    top = -1;
22  }
23  boolean isEmpty() {
24    return top == -1;
25  }
26  boolean isFull() {
27    return top == data.length - 1;
28  }
29  int size() {
30    return top + 1;
31  }
32  void push(int value) {
33    if (isFull()) {
34      throw new IllegalStateException("Stack overflow: full.");
35    }
36    top++;
37    data[top] = value;
38  }
39  int pop() {
40    if (isEmpty()) {
41      throw new IllegalStateException("Stack underflow: empty.");
42    }
43    int value = data[top];
44    top--;
45    return value;
46  }
47  int peek() {
48    if (isEmpty()) {
49      throw new IllegalStateException("Stack underflow: empty.");
50    }
51    return data[top];
52  }
53}

▶ This program runs as is. Try it in the Programiz online compiler: tap Copy, paste it there, and press Run.

Java's own stack: Stack<Integer>

Java has no ArrayStack, but it does come with ready-made stack classes, so real programs seldom write their own. The oldest is java.util.Stack, and exams often ask you to trace it. It has the same five methods as our ArrayStack: push, pop, peek, isEmpty, and size. Here is a short program that uses it:

 1import java.util.Stack;
 2
 3public class Main {
 4  public static void main(String[] args) {
 5    Stack<Integer> stack = new Stack<>();
 6    stack.push(10);
 7    stack.push(20);
 8    stack.push(30);
 9    System.out.println(stack.peek());
10    System.out.println(stack.pop());
11    System.out.println(stack.size());
12    System.out.println(stack);
13    stack.pop();
14    System.out.println(stack.isEmpty());
15    System.out.println(stack.pop());
16    System.out.println(stack.isEmpty());
17  }
18}

▶ This program runs as is. Try it in the Programiz online compiler: tap Copy, paste it there, and press Run.

Two lines are new. This table shows how to read them aloud:

CodeRead it asWhat it means
import java.util.Stack;"use the Stack class from java.util"java.util is Java's toolbox of ready-made data structures. Without this line, Java does not know the name Stack.
Stack<Integer> stack"stack is a Stack of Integers"The type inside < > says what kind of items the stack holds.
= new Stack<>()"make a new, empty Stack"The empty <> copies the type from the left side. There is no capacity: a Stack grows by itself, so it never overflows.
System.out.println(stack)"print the whole stack"Prints every item in square brackets, bottom → top, like [10, 20]. That is the same order as our trace tables.

Generics: the type in < >

A class like Stack can hold any type of item. You choose the type in angle brackets when you make one: Stack<Integer> holds whole numbers, and Stack<String> holds strings. This feature is called generics. Java then checks every call for you: stack.push("hi") on a Stack<Integer> is a compile error.

Why Integer, not int?

The type inside < > must be a class, and int is not a class (it is a primitive type). Integer is the class version of int. Java converts between the two for you, so stack.push(10) and int x = stack.pop(); just work. Stack<int> is a compile error. You will see the same <Integer> again in Queues, Graphs, BFS, and Maps.

Now trace the program in a table, the same way as Part 3. Try it on paper first, then check:

Show the trace and the output

One row per line that calls the stack. "Printed" is what println shows; a call can return a value that nothing prints.

LineCallStack after (bottom → top)ReturnedPrinted
6push(10)10—
7push(20)10, 20—
8push(30)10, 20, 30—
9peek()10, 20, 303030
10pop()10, 203030
11size()10, 2022
12print the stack10, 20—[10, 20]
13pop()1020(not printed)
14isEmpty()10falsefalse
15pop()(empty)1010
16isEmpty()(empty)truetrue

Output (checked in Java):

30
30
2
[10, 20]
false
10
true

The newer choice: ArrayDeque

Stack dates from the first version of Java, and it has extra methods that break the stack rule (for example, get(0) reads the bottom item). Java's documentation says to use a deque ("deck," a double-ended queue) instead, such as ArrayDeque, which is also usually faster. It has the same push, pop, and peek:

 1import java.util.ArrayDeque;
 2
 3public class Main {
 4  public static void main(String[] args) {
 5    ArrayDeque<Integer> stack = new ArrayDeque<>();
 6    stack.push(10);
 7    stack.push(20);
 8    stack.push(30);
 9    System.out.println(stack.pop());    // 30
10    System.out.println(stack.peek());   // 20
11    System.out.println(stack);          // [20, 10]  top first!
12  }
13}

▶ This program runs as is. Try it in the Programiz online compiler: tap Copy, paste it there, and press Run.

Exam trap: printing an ArrayDeque

println shows an ArrayDeque top first: [20, 10]. A Stack with the same items prints [10, 20]. The stack is the same (20 is on top); only the printing order differs. In a trace table, still write the stack bottom → top.

The three stacks side by side:

Our ArrayStackJava's StackJava's ArrayDeque
Items kept ina fixed-size arrayan array that growsan array that grows
Can it get full?yes (overflow)nono
pop() when emptyIllegalStateExceptionEmptyStackExceptionNoSuchElementException
peek() when emptyIllegalStateExceptionEmptyStackExceptionreturns null (no exception)
println order(we did not write one)bottom → toptop → bottom
Use it forlearning what happens insideexams and older codenew programs

All three are the same stack ADT: the same LIFO rule and the same methods, kept in different ways. In this course you still write your own, so you can see what happens inside.

Good to know: StackOverflowError

You may also meet StackOverflowError. That is overflow on Java's own stack of method calls, usually from a recursive method that never stops. You will see it in the Recursion lesson.

A stack built from a linked list

A stack can also use a linked list, with the first node as the top. Then push is "insert at the beginning" and pop is "delete the first node," the same two operations from the Linked lists lesson. It never gets full, so it has no isFull().

 1class LinkedStack {
 2  Node top;   // the first node is the top; null means empty
 3
 4  void push(int value) {
 5    Node newNode = new Node(value);
 6    newNode.next = top;   // step 1: the new node points to the old top
 7    top = newNode;        // step 2: top moves to the new node
 8  }
 9  int pop() {
10    if (top == null) {
11      throw new IllegalStateException("Stack underflow: empty.");
12    }
13    int value = top.data;
14    top = top.next;       // delete the first node
15    return value;
16  }
17}

It uses the same Node class as the Linked lists lesson. LIFO is the rule; an array or a linked list is just where the items are kept.

Part 5 · Watch out

Common mistakes

Mistake 1: storing before moving top

Situation: a student swaps the two lines of push:

data[top] = value;   // stores first...
top++;               // ...then moves

What goes wrong: top is the index of the current top item. On an empty stack, data[-1] = value; crashes with an ArrayIndexOutOfBoundsException. On a stack holding 4, 9, the new value writes over the 9.

Fix: move first (top++;), then store (data[top] = value;).

Mistake 2: thinking pop erases the cell

Situation: after pop() on 4, 9, a student writes that data[1] is now 0.

What goes wrong: pop only moves top down. The 9 is still in cell 1 (see step 9 of the walkthrough). It is not part of the stack because it is above top, and the next push writes over it.

✗ After pop()data = [4, 0, 0]

✓ After pop()data = [4, 9, 0], top = 0

Mistake 3: using peek to remove

Situation: a program calls peek() in a loop, hoping to empty the stack.

What goes wrong: peek() never moves top, so it returns the same top item every time and the stack never shrinks.

Fix: use pop() to remove; use peek() only to look.

Part 6 · Your turn

Practice

Set A is the Section 5 self-check from your module, in case you want to redo it. Set B is new. The coding task at the end runs in Java.

Set A: from the module

  1. Write exactly what this prints.
    ArrayStack s = new ArrayStack(3);
    s.push(4);
    s.push(9);
    System.out.println(s.pop());
    s.push(2);
    System.out.println(s.peek());
    System.out.println(s.size());
    System.out.println(s.isFull());
  2. In your own words, what is the difference between pop() and peek()? Which line of code shows it?
Show the answers
  1. 9, 2, 2, false (one per line). pop() removes 9. After push(2) the stack is 4, 2, so peek() shows 2 and size() is 2. With capacity 3, it is not full.
  2. pop() removes the top item and returns it; peek() returns it and leaves the stack unchanged. The line top--; in pop() is the difference.

Set B: new problems

  1. The statements run in order, starting with an empty stack. Copy the table and fill it in. The first row is done for you.
    ArrayStack s = new ArrayStack(4);
    s.push(5);
    s.push(8);
    s.pop();
    s.push(3);
    s.push(6);
    s.peek();
    s.pop();
    s.pop();
    StatementStack after (bottom → top)Value returned
    s.push(5);5—
    s.push(8);
    s.pop();
    s.push(3);
    s.push(6);
    s.peek();
    s.pop();
    s.pop();
  2. Inside the array. After this code, (a) what is top? (b) What is in data[1] and data[2]? (c) Is 33 part of the stack? Why?
    ArrayStack s = new ArrayStack(3);
    s.push(11);
    s.push(22);
    s.push(33);
    s.pop();
    s.pop();
    s.push(44);
  3. Push the characters of IT2C one at a time (I first), then pop until the stack is empty. Write the characters in the order they come out.
  4. What does this print? What happens on the last line?
    ArrayStack s = new ArrayStack(2);
    s.push(1);
    System.out.println(s.pop());
    System.out.println(s.pop());
Show the answers

For self-study, not for grading. All answers were checked by running the code in Java.

  1. StatementStack after (bottom → top)Value returned
    s.push(5);5—
    s.push(8);5, 8—
    s.pop();58
    s.push(3);5, 3—
    s.push(6);5, 3, 6—
    s.peek();5, 3, 66
    s.pop();5, 36
    s.pop();53
  2. (a) top is 1. After the two pops it was 0; push(44) moved it to 1. (b) data[1] is 44 (it wrote over 22), and data[2] is still 33. (c) No. 33 is above top, so it is not part of the stack. The stack is 11, 44.
  3. C, 2, T, I. C was pushed last, so it comes out first: the word comes out reversed, C2TI.
  4. It prints 1. The second pop() finds the stack empty, so it throws an IllegalStateException with the message "Stack underflow: empty." and the program stops (underflow).

Your coding task: decimal to binary

To write a number in binary, divide it by 2 again and again, and keep each remainder. The catch: the remainders come out in the wrong order. The last remainder is the first binary digit. A stack fixes that for free: push each remainder, then pop them all. Here is 6, step by step:

nn % 2 (push it)n / 2 (the new n)
603
311
110, so stop

The stack now holds 0, 1, 1 (bottom → top). Popping gives 1, 1, 0, so 6 is 110 in binary.

Finish toBinary in about 6 lines where it says YOUR CODE. ArrayStack is the class from Part 4, with only the methods this task needs. Run it: each printed line must match its comment.

 1public class Main {
 2  // Returns n written in binary, for example toBinary(6) gives "110".
 3  static String toBinary(int n) {
 4    if (n == 0) {
 5      return "0";
 6    }
 7    ArrayStack s = new ArrayStack(32);
 8    String result = "";
 9    // YOUR CODE:
10    // 1. While n > 0: push the remainder n % 2,
11    //    then divide: n = n / 2.
12    // 2. While the stack is not empty: pop a digit
13    //    and add it to the end of result.
14
15    return result;
16  }
17
18  public static void main(String[] args) {
19    System.out.println(toBinary(6));    // expected: 110
20    System.out.println(toBinary(13));   // expected: 1101
21    System.out.println(toBinary(20));   // expected: 10100
22    System.out.println(toBinary(1));    // expected: 1
23    System.out.println(toBinary(0));    // expected: 0
24  }
25}
26
27class ArrayStack {
28  int[] data;
29  int top;
30
31  ArrayStack(int capacity) {
32    data = new int[capacity];
33    top = -1;
34  }
35  boolean isEmpty() {
36    return top == -1;
37  }
38  boolean isFull() {
39    return top == data.length - 1;
40  }
41  void push(int value) {
42    if (isFull()) {
43      throw new IllegalStateException("Stack overflow: full.");
44    }
45    top++;
46    data[top] = value;
47  }
48  int pop() {
49    if (isEmpty()) {
50      throw new IllegalStateException("Stack underflow: empty.");
51    }
52    int value = data[top];
53    top--;
54    return value;
55  }
56}

▶ This program runs as is. Try it in the Programiz online compiler: tap Copy, paste it there, and press Run.

Show one possible answer
 1static String toBinary(int n) {
 2  if (n == 0) {
 3    return "0";
 4  }
 5  ArrayStack s = new ArrayStack(32);
 6  String result = "";
 7  while (n > 0) {
 8    s.push(n % 2);
 9    n = n / 2;
10  }
11  while (!s.isEmpty()) {
12    result = result + s.pop();
13  }
14  return result;
15}

Output, one per line: 110, 1101, 10100, 1, 0.

n / 2 divides two ints, so the decimal part is dropped: 13 / 2 is 6. The part that was dropped is exactly n % 2, the remainder we push. The first loop stops when n reaches 0.

The second loop is the stack doing its job. The remainders went in last-digit-first, and LIFO brings them out first-digit-first, just as IT2C came out as C2TI in Set B. result + s.pop() joins text and a number, so "" + 1 gives "1", then "1" + 1 gives "11", and so on.

Why the if (n == 0) at the start? With 0, the first loop never runs, nothing is pushed, and result stays empty. But 0 in binary is 0, not an empty line.

Part 7 · Check yourself

Self-check

Not graded. Tap an answer to see if you got it, and read why.

  1. A stack follows which rule?

  2. Push 1, push 2, push 3, then pop. What is returned?

  3. What is the difference between pop() and peek()?

  4. In ArrayStack, a new stack has top = -1. What does size() return?

  5. An ArrayStack holds 4, 9 (so top is 1). After pop(), what is in data[1]?

  6. A program runs s.pop(); on its own line, without printing it. What happens?

  7. Why does push run top++; before data[top] = value;?

  8. After Stack<Integer> s = new Stack<>(); s.push(5); s.push(6); s.push(7); s.pop(); what does System.out.println(s); print?

  9. Why does Stack<int> not compile?

Score: 0 / 9

Key takeaways

  1. Stack: last in, first out. push, pop, and peek all happen at the top.
  2. pop removes and returns the top item; peek only looks.
  3. In ArrayStack, top is the index of the top item: -1 means empty, and the size is top + 1.
  4. push moves top up, then stores. pop leaves the old value in its cell, above top.
  5. Guard against underflow (empty) and overflow (full) before acting.

Next lesson: Queues, where the oldest item leaves first.

References

  1. R. Sedgewick and K. Wayne, Algorithms, 4th ed. Addison-Wesley, 2011, Section 1.3 (Bags, Queues, and Stacks). algs4.cs.princeton.edu
  2. P. Morin, "ArrayStack: Fast Stack Operations Using an Array," Section 2.1 in Open Data Structures. opendatastructures.org
  3. Oracle, "Class IllegalStateException," Java SE 21 API. docs.oracle.com
  4. Oracle, "How to Throw Exceptions," The Java Tutorials. docs.oracle.com
  5. ITC 120 Data Structures and Algorithms Syllabus, Faculty of Computing, Engineering, and Technology, Davao Oriental State University.