G27
Self-checkedTier 1 14 min readpds.stack-adt

Stack (abstract data type)

A stack lets you add and remove only at one end, so the last item in is the first out. Learn push, pop and peek, the array implementation with a top index (and how the top = -1 versus top = 0 convention changes every answer), overflow and underflow, and the classic GATE question of which output orders a stack can produce.

Why it exists

Many tasks need to remember things in the order they were met and then deal with the most recent one first: undoing the last edit, going back through the pages you visited, matching the most recently opened bracket, returning from the function that was called last. A stack gives exactly this behaviour and nothing more. Restricting yourself to one end is what makes the structure fast (every operation is constant time) and easy to reason about.

Prerequisites

Precise definitions

  • Abstract data type (ADT). A description of what a structure does (its operations and their rules), not how it is stored. A stack can be built on an array or on a linked list; the user of the ADT does not care.
  • Stack. A collection in which items are added and removed only at one end, called the top. The item removed is always the one added most recently: LIFO (last in, first out).
  • Operations.
OperationWhat it doesCost (array or list)
push(x)put x on topO(1)O(1)
pop()remove and return the top itemO(1)O(1)
peek() (also top())return the top item without removing itO(1)O(1)
isEmpty()true if there are no itemsO(1)O(1)
isFull()true if no room is left (array version only)O(1)O(1)
  • Overflow. push on a full (array) stack. Underflow. pop or peek on an empty stack. A correct implementation checks for both.
  • Array implementation. Keep the items in s[0 .. N-1] and an integer top. This page uses the most common convention:
    • top = -1 means empty. push(x) is s[++top] = x. pop() is return s[top--].
    • The number of items is top + 1. The stack is full when top == N - 1.
  • The other convention. Some books (K&R's calculator, for instance, keeps sp this way) keep top as "the index of the next free cell": top = 0 means empty, push(x) is s[top++] = x, pop() is return s[--top], the number of items is top, and the stack is full when top == N. Both are correct. A GATE question that shows code or gives the starting value of top tells you which one applies. Never mix them.
  • Linked implementation. Each item is a node. push inserts a new node at the head and pop removes the head node. No fixed size, no overflow (until memory runs out). See linked lists.

How it works

The animation below runs a real stack made of an array s[5] and an index top. Step through it and watch two things:

  1. push first changes top, then writes the cell. pop first reads the cell, then changes top.
  2. pop does not erase anything. After the first pop the 30 is still in s[2]; it is just no longer part of the stack, and the next push overwrites it.

A stack kept in an array with a top index

Real run, real addresses

C source

1#include <stdio.h>
2
3#define N 5
4
5int main(void) {
6 int s[N] = {0};
7 int top = -1;
8 s[++top] = 10;
9 s[++top] = 20;
10 s[++top] = 30;
11 int x = s[top--];
12 s[++top] = 40;
13 x = s[top--];
14 x = s[top--];
15 x = s[top--];
16 return 0;
17}

Stack

sint

0…d5e0
[0]
0…d5e4
[1]
0…d5e8
[2]
0…d5ec
[3]
0…d5f0
[4]

topint

-1…d5dc

Amber = changed in this step. Hover a cell for its full address. Arrows show where a pointer points; the small tag under a cell names the pointers aimed at it.

Step 1

The stack lives in an array of N = 5 cells. top is the index of the newest element, and -1 means empty. The cells hold 0 only because we initialised them.

1 / 9
push is ++top then store; pop is read then top--. The array never shrinks: only top moves. Produced by: real execution: every address and value is read from memory by the running program at each step. gcc (Debian 14.2.0-19) 14.2.0. gcc -O0 -o prog prog.c && setarch x86_64 -R ./prog (ASLR off so the numbers are stable)

Which output orders can a stack produce?

Suppose the numbers 1,2,…,n1, 2, \ldots, n are pushed in that order, but pops may be interleaved with pushes in any way. The numbers come out in some order. Which orders are possible?

  • Take any output order. If, for some three numbers a<b<ca < b < c, it prints cc first, then aa, then bb, the order is impossible. (To print cc first, aa and bb must already be on the stack with bb above aa, so bb would come out before aa.) This is the forbidden pattern "3 1 2".
  • The number of possible orders is the Catalan number Cn=1n+1(2nn)C_n = \frac{1}{n+1}\binom{2n}{n}: 1, 2, 5, 14, 42 for n=1,…,5n = 1, \ldots, 5.
  • To test one particular order, simulate it: to print the next wanted number, keep pushing input numbers until it is on top, then pop it. If it is buried under another number, the order is impossible.

Worked examples

EX 1A stack in an array, with overflow and underflow checks

Easy
#include <stdio.h>
 
#define N 4
 
static int s[N];
static int top = -1;
 
static int push(int x) {
    if (top == N - 1) return 0;
    s[++top] = x;
    return 1;
}
 
static int pop(int *x) {
    if (top == -1) return 0;
    *x = s[top--];
    return 1;
}
 
int main(void) {
    int x;
    for (int v = 1; v <= 5; v++)
        printf("push %d %s\n", v * 10, push(v * 10) ? "ok" : "overflow");
    while (pop(&x)) printf("%d ", x);
    printf("\n%s\n", pop(&x) ? "popped" : "underflow");
    return 0;
}

Output:

push 10 ok
push 20 ok
push 30 ok
push 40 ok
push 50 overflow
40 30 20 10
underflow

Reading it. The stack holds at most N = 4 items. The fifth push finds top == N - 1 and is refused. Popping repeatedly returns the items in the reverse of the order they went in. A pop on the now-empty stack is refused.

EX 2Trace a mixed sequence of pushes and pops

Medium
#include <stdio.h>
 
int main(void) {
    int s[10], top = -1;
    s[++top] = 1;
    s[++top] = 2;
    printf("%d ", s[top--]);
    s[++top] = 3;
    s[++top] = 4;
    printf("%d ", s[top--]);
    printf("%d ", s[top--]);
    s[++top] = 5;
    printf("%d ", s[top--]);
    printf("%d\n", s[top--]);
    return 0;
}

Output:

2 4 3 5 1

Trace. Write the stack as a list with the top on the right.

OperationStack afterPrinted
push 1[1]
push 2[1, 2]
pop[1]2
push 3[1, 3]
push 4[1, 3, 4]
pop[1, 3]4
pop[1]3
push 5[1, 5]
pop[1]5
pop[]1

EX 3Which permutations can a stack produce?

GATE level
#include <stdio.h>
 
static int valid(const int *p, int n) {
    int st[8], top = -1, next = 1;
    for (int i = 0; i < n; i++) {
        while (top < 0 || st[top] != p[i]) {
            if (next > n) return 0;
            st[++top] = next++;
        }
        top--;
    }
    return 1;
}
 
static int count(int *p, int used, int n, int k) {
    if (k == n) return valid(p, n);
    int c = 0;
    for (int v = 1; v <= n; v++) {
        if (used & (1 << v)) continue;
        p[k] = v;
        c += count(p, used | (1 << v), n, k + 1);
    }
    return c;
}
 
int main(void) {
    int p[8];
    int a[4] = {3, 1, 2, 4}, b[4] = {2, 1, 4, 3};
    int c4 = count(p, 0, 4, 0);
    int c5 = count(p, 0, 5, 0);
    int va = valid(a, 4);
    int vb = valid(b, 4);
    printf("%d %d %d %d\n", c4, c5, va, vb);
    return 0;
}

Output:

14 42 0 1

Reading it. The program tries all 4!=244! = 24 and 5!=1205! = 120 orders and counts the ones a stack can produce: 14 and 42, which are the Catalan numbers C4C_4 and C5C_5. The order 3, 1, 2, 4 is impossible (it contains the pattern 3 1 2), while 2, 1, 4, 3 is possible: push 1, push 2, pop (2), pop (1), push 3, push 4, pop (4), pop (3).

Shortcut for an exam. Look for three numbers a<b<ca < b < c that appear in the output in the order c,a,bc, a, b (not necessarily next to each other). If you find such a triple, the order is impossible.

EX 4Two stacks in one array

Medium
#include <stdio.h>
 
#define N 6
 
static int a[N];
static int t1 = -1, t2 = N;
 
static int push1(int x) {
    if (t1 + 1 == t2) return 0;
    a[++t1] = x;
    return 1;
}
 
static int push2(int x) {
    if (t1 + 1 == t2) return 0;
    a[--t2] = x;
    return 1;
}
 
int main(void) {
    push1(1);
    push1(2);
    push1(3);
    push1(4);
    push2(9);
    push2(8);
    int r = push1(5);
    printf("%d %d %d %d\n", t1, t2, r, (t1 + 1) + (N - t2));
    return 0;
}

Output:

3 4 0 6

Reading it. The first stack grows from the left end (t1 starts at -1), the second from the right end (t2 starts at N). Space is shared: neither stack overflows until the two tops meet. The array is full exactly when t1 + 1 == t2. Here the first stack holds 4 items and the second 2, all 6 cells are used, and a further push is refused. Two separate arrays of size 3 would have refused the 4th item of the first stack even though the second stack had a free cell; sharing avoids that waste. Popping from the second stack is the mirror image: read a[t2], then t2++ (it is empty when t2 == N).

EX 5Reversing a string with a stack

Medium
#include <stdio.h>
#include <string.h>
 
int main(void) {
    const char *in = "GATE";
    char st[16];
    int top = -1;
    for (size_t i = 0; i < strlen(in); i++) st[++top] = in[i];
    while (top >= 0) putchar(st[top--]);
    putchar('\n');
    return 0;
}

Output:

ETAG

Reading it. Each letter is pushed in order and then popped. Last in, first out reverses the order. This is the simplest example of a stack turning "the order I met things" into "most recent first".

EX 6A stack built on a linked list

Medium
#include <stdio.h>
#include <stdlib.h>
 
struct node {
    int data;
    struct node *next;
};
 
static struct node *top;
 
static void push(int x) {
    struct node *n = malloc(sizeof *n);
    if (n == NULL) exit(1);
    n->data = x;
    n->next = top;
    top = n;
}
 
static int pop(void) {
    struct node *n = top;
    int x = n->data;
    top = n->next;
    free(n);
    return x;
}
 
int main(void) {
    push(1);
    push(2);
    push(3);
    int a = pop();
    int b = pop();
    int c = pop();
    printf("%d %d %d\n", a, b, c);
    return 0;
}

Output:

3 2 1

Reading it. push is "insert at the front of the list" and pop is "delete the first node", both O(1)O(1) and with no size limit. The three pops are in separate statements on purpose: if they were three arguments of one printf, C would not say in which order they run.

Cheat box

Cheat box

  • LIFO. All access at the top. push, pop, peek, isEmpty, all O(1)O(1).
  • Array stack, top = -1 start: push is s[++top] = x, pop is s[top--], items == top + 1, full when top == N - 1, empty when top == -1.
  • Array stack, top = 0 start: push is s[top++] = x, pop is s[--top], items == top, full when top == N, empty when top == 0.
  • pop does not erase the cell; it only moves top.
  • Pushing in order 1,…,n1, \ldots, n: the number of possible output orders is the Catalan number 1n+1(2nn)\frac{1}{n+1}\binom{2n}{n} (1, 2, 5, 14, 42, 132). Forbidden pattern: c,a,bc, a, b with a<b<ca < b < c.
  • Two stacks in one array: grow from both ends, full when t1 + 1 == t2.
  • Linked stack: push and pop at the head.
  • Overflow is a full push. Underflow is an empty pop or peek.

Traps and GATE patterns

Connections

Function calls use a stack: each call pushes an activation record and each return pops it (recursion and the call stack, and the compiler's activation records). The next topic, stack applications, uses the structure for bracket matching, expression conversion and evaluation. The opposite discipline is the queue: first in, first out.

PYQs

7 previous year questions from your book. I re-solved each one myself (6 by running or simulating, 1 by reasoning only); the book's key is shown next to my answer. All PYQs

GATE 2026 · Set 2 · MSQ · 2 marksQ1 · page 61 of the book
Consider a stack S and a queue Q. Both of them are
initially empty and have the capacity to store ten
elements each. The elements 1,2,3,4, and 5 arrive
one by one, in that order. When an element arrives,
it is assigned either to S (pushed on S ) or to Q
(enqueued to Q ). Once all the five elements are
stored, the output is generated in two steps. First,
stack S is emptied by popping all elements. Then
queue Q is emptied by dequeueing all elements.
The output obtained by following this process is
43125 .
Given the output, the objective is to predict whether
an element was assigned to S or Q.
Which of the following options is/are possible valid
assignment(s) of the elements?
Note: In the options, the notation xS denotes that
element x was assigned to S and yQ denotes that
element y was assigned to Q.
  • (a)1S,2Q,3S,4S,5Q
  • (b)1Q,2Q,3S,4S,5Q
  • (c)1Q,2Q,3Q,4S,5S
  • (d)1S,2S,3S,4Q,5Q
GATE 2021 · NAT · 1 markQ2 · page 61 of the book
Consider the following sequence of operations on
an empty stack.
push(54); push(52); pop(); push(55); push(62); s =
pop();
Consider the following sequence of operations on
an empty queue.
enqueue (21); enqueue (24); dequeue (); enqueue
(28); enqueue (32); q = dequeue();
The value of s +q is
.
We maintain exactly two external pointers FRONT
and REAR pointing to the front node and the rear
node of the queue, respectively. Which of the
following statements is/are CORRECT for such a
circular queue, so that insertion and deletion
operations can be performed in O(1) time?
I. Next pointer of front node points to the rear node.
II. Next pointer of rear node points to the front node.
  • (a)I only
  • (b)II only
  • (c)Both I and II
  • (d)Neither I nor II
GATE 2016 · Set 1 · NAT · 2 marksQ5 · page 61 of the book
Let Q denote a queue containing sixteen numbers and
S be an empty stack. Head(Q) returns the element at
the head of the queue Q without removing it from Q.
Similarly Top(S) returns the element at the top of S
without removing it from S. Consider the algorithm
given below.
GATE 2015 · Set 2 · NAT · 2 marksQ7 · page 62 of the book
Consider the C program below
#include <stdio.h>
int *A, stkTop;
int stkFunc (int opcode, int val)
{
static int size=0, stkTop=0;
switch (opcode) {
case -1: size = val; break;
case 0: if (stkTop< size )
A[stkTop++]=val; break;
default: if (stkTop) return A[--stkTop];
}
return -1;
}
int main()
{
int B[20]; A=B; stkTop = -1;
stkFunc (-1, 10);
stkFunc (0, 5);
stkFunc (0, 10);
printf ("%d\n", stkFunc(1, 0)+ stkFunc(1, 0));
}
The value printed by the above program is

.
GATE 2013 · MCQ · 2 marksQ8 · page 62 of the book
Suppose a stack implementation supports an
instruction REVERSE, which reverses the order of
elements on the stack, in addition to the PUSH and
POP instructions. Which one of the following
statements is TRUE (with respect to this modified
stack)?
  • (a)A queue cannot be implemented using this stack.
  • (b)A queue can be implemented where ENQUEUE takes a single instruction and DEQUEUE takes a sequence of two instructions.
  • (c)A queue can be implemented where ENQUEUE takes a sequence of three instructions and DEQUEUE takes a single instruction.
  • (d)A queue can be implemented where both ENQUEUE and DEQUEUE take a single instruction each.
GATE 2006 · MCQQ12 · page 63 of the book
An implementation of a queue Q, using two stacks
S1 and S2, is given below:
void insert (Q, x) {
push(S1, x);
GATE 2005 · MCQ · 1 markQ13 · page 63 of the book
An Abstract Data Type (ADT) is:
  • (a)same as an abstract class
  • (b)a data type that cannot be instantiated
  • (c)a data type for which only the operations defined on it can be used, but none else
  • (d)All of the above

Self-check

Question 1

An empty stack receives: push 5, push 8, pop, push 2, push 7, pop, pop. What is the content of the stack (bottom to top) and what was printed by the three pops?

Show answer

After push 5, push 8: [5, 8]. Pop gives 8: [5]. Push 2, push 7: [5, 2, 7]. Pop gives 7: [5, 2]. Pop gives 2: [5]. The pops printed 8, 7, 2, and the stack is [5].

Question 2

The numbers 1, 2, 3, 4, 5 are pushed in this order with pops interleaved arbitrarily. How many different output orders are possible? Is 4, 3, 5, 1, 2 one of them?

Show answer

The count is the Catalan number C5=16(105)=42C_5 = \frac{1}{6}\binom{10}{5} = 42. The order 4, 3, 5, 1, 2 is impossible: after 4, 3, 5 have been output, the stack holds 1, 2 with 2 on top, so 2 must come out before 1. It contains the pattern 5, 1, 2 (a larger number followed by a smaller and then a number between them).

Question 3

An array stack of size 10 uses the convention "top is the index of the next free cell", starting at 0. After 7 pushes and 2 pops, what is top, how many items are stored, and how many more pushes fit?

Show answer

top =7−2=5= 7 - 2 = 5. The number of items equals top, so 5. The stack is full when top == 10, so 10−5=510 - 5 = 5 more pushes fit.

Question 4

Two stacks share one array of 100 cells, growing towards each other. After the first has 40 items, how many items can the second hold at most?

Show answer

The array has 100 cells and 40 are used, so the second stack can hold up to 60 items before the tops meet.

Question 5

Why can push and pop both be done in constant time with a linked list, even though a linked list does not support quick access to its last node?

Show answer

Both operations touch only the first node. push makes a new node point at the old head and moves head to it. pop moves head to the second node. Neither needs to walk the list.

Revision card

One-screen revision

  • Stack = LIFO. push, pop, peek, isEmpty are all O(1)O(1).
  • top = -1 convention: s[++top] = x; s[top--]; items = top + 1; full at N - 1.
  • top = 0 convention: s[top++] = x; s[--top]; items = top; full at N.
  • pop only moves top; the cell keeps its old value.
  • Overflow: push on full. Underflow: pop on empty.
  • Valid output orders of 1..n1..n: Catalan number. Forbidden pattern c,a,bc, a, b with a<b<ca < b < c.
  • Two stacks in one array: from both ends, full when t1 + 1 == t2.
  • Linked stack: push and pop at the head.

References

  • ·Kernighan and Ritchie, The C Programming Language, 2nd ed., Section 4.3 External Variables (a stack-based calculator, with push and pop), Section 4.5 Header Files
  • ·Cormen, Leiserson, Rivest, Stein, Introduction to Algorithms, 3rd ed., Section 10.1 Stacks and queues

Verification

The animation replays a real run of an instrumented C program: every cell and index is read from memory at each step, and the test suite checks that pop leaves the old value in the cell until a push overwrites it. All C programs on this page are compiled with -Wall -Wextra -Werror and run by npm run verify:c, also under AddressSanitizer and UBSan. The stack-permutation counts (14 for 4 items, 42 for 5) come from a program that tries every permutation, not from the Catalan formula. The textbook section numbers were written from memory and have NOT been checked against the books. The prose and the GATE-pattern claims have NOT yet had a human textbook check (the independent second pass is described at the end of these notes). SECOND PASS (2026-11-02, done by the assistant, not a human check): every Self-check question was solved before the printed answer was read and all agreed; the definitions, worked examples, cheat box and traps were read claim by claim and the numbers re-derived by hand (long C programs were not re-read line by line: they are compiled and compared by npm run verify:c, and their printed outputs were checked against the prose). No defect found. Status raised to self-checked; verified needs a textbook or human check.

last verified: never