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.
| Operation | What it does | Cost (array or list) |
|---|---|---|
push(x) | put x on top | |
pop() | remove and return the top item | |
peek() (also top()) | return the top item without removing it | |
isEmpty() | true if there are no items | |
isFull() | true if no room is left (array version only) |
- Overflow.
pushon a full (array) stack. Underflow.poporpeekon an empty stack. A correct implementation checks for both. - Array implementation. Keep the items in
s[0 .. N-1]and an integertop. This page uses the most common convention:top = -1means empty.push(x)iss[++top] = x.pop()isreturn s[top--].- The number of items is
top + 1. The stack is full whentop == N - 1.
- The other convention. Some books (K&R's calculator, for instance, keeps
spthis way) keeptopas "the index of the next free cell":top = 0means empty,push(x)iss[top++] = x,pop()isreturn s[--top], the number of items istop, and the stack is full whentop == N. Both are correct. A GATE question that shows code or gives the starting value oftoptells you which one applies. Never mix them. - Linked implementation. Each item is a node.
pushinserts a new node at the head andpopremoves 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:
pushfirst changestop, then writes the cell.popfirst reads the cell, then changestop.popdoes not erase anything. After the first pop the 30 is still ins[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 addressesC source
Stack
sint
topint
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.
Which output orders can a stack produce?
Suppose the numbers 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 , it prints first, then , then , the order is impossible. (To print first, and must already be on the stack with above , so would come out before .) This is the forbidden pattern "3 1 2".
- The number of possible orders is the Catalan number : 1, 2, 5, 14, 42 for .
- 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
underflowReading 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 1Trace. Write the stack as a list with the top on the right.
| Operation | Stack after | Printed |
|---|---|---|
| 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 1Reading it. The program tries all and orders and counts the ones a stack can produce: 14 and 42, which are the Catalan numbers and . 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 that appear in the output in the order (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 6Reading 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:
ETAGReading 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 1Reading it. push is "insert at the front of the list" and pop is "delete the first node", both 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 . - Array stack,
top = -1start:pushiss[++top] = x,popiss[top--], itemstop + 1, full whentop == N - 1, empty whentop == -1. - Array stack,
top = 0start:pushiss[top++] = x,popiss[--top], itemstop, full whentop == N, empty whentop == 0. popdoes not erase the cell; it only movestop.- Pushing in order : the number of possible output orders is the Catalan number (1, 2, 5, 14, 42, 132). Forbidden pattern: with .
- 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
Unlocks
Across subjects
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
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
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
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.
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
.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.
An implementation of a queue Q, using two stacks
S1 and S2, is given below:
void insert (Q, x) {
push(S1, x);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 answerHide
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 answerHide
The count is the Catalan number . 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 answerHide
top . The number of items equals top, so 5. The stack is full when top == 10, so 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 answerHide
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 answerHide
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,isEmptyare all . top = -1convention:s[++top] = x;s[top--]; items =top + 1; full atN - 1.top = 0convention:s[top++] = x;s[--top]; items =top; full atN.poponly movestop; the cell keeps its old value.- Overflow: push on full. Underflow: pop on empty.
- Valid output orders of : Catalan number. Forbidden pattern with .
- 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
My notes (saved in this browser)