By the end of this chapter you'll be able to…

  • 1State the heap property and what it deliberately does not constrain
  • 2Explain why a heap cannot be searched efficiently
  • 3Explain why no traversal of a heap gives sorted order
  • 4Apply the index formulas under both 0-based and 1-based conventions
  • 5Locate the last internal node and count the leaves of a heap
  • 6Describe sift-up and sift-down and state their costs
  • 7Explain why insertion appends and extraction moves the last element
  • 8State the cost of every heap operation including search
  • 9Explain why building a heap by sifting down costs linear time
  • 10Explain why inserting one at a time genuinely costs n log n
  • 11State the properties of heapsort including stability and cache behaviour
  • 12Compare heapsort with quicksort and merge sort
  • 13Name the algorithms that use a priority queue
  • 14Compute the maximum edge count for directed and undirected graphs
  • 15Apply the degree-sum relation in both directed and undirected graphs
  • 16Distinguish strong from weak connectivity
  • 17State the minimum edges for connectivity and the threshold forcing a cycle
  • 18Compare adjacency matrix and adjacency list on space and query cost
  • 19Explain why density decides the representation
  • 20Interpret the k-th power of an adjacency matrix
  • 21State the cost of breadth-first and depth-first search under both representations
  • 22Explain why breadth-first search gives unweighted shortest paths
  • 23Classify depth-first search edges and state which occur in undirected graphs
  • 24Prove that a back edge exists exactly when a directed graph has a cycle
💡
Why this chapter matters in GATE
Two structures that look unrelated share a design philosophy: both maintain exactly as much information as their intended queries need and no more. A binary search tree maintains a total order, which is why it answers range queries; a heap maintains only a partial order, with every parent dominating its children and nothing known about siblings, which is why it cannot search but can produce the extreme element in constant time and restore itself in logarithmic time. That deliberate weakness is what makes a heap cheap to maintain and why a priority queue uses one rather than a search tree. Graphs make the same trade in the representation rather than the invariant: an adjacency matrix answers edge existence in constant time at quadratic space cost, while an adjacency list answers neighbour listing in degree time at linear space cost. Neither is better, and density decides which is right.

Before you start — revise these

🔗
Trees & Binary Search Trees
Completeness, height bounds and the contrast between total and partial order are what distinguish a heap from a search tree.
🔗
Arrays, Stacks, Queues & Linked Lists
The array representation of a heap and the queue and stack that drive the two graph traversals are all built from those structures.
🔗
Discrete Mathematics
Graph terminology, degree sums, connectivity and the edge threshold for a cycle are developed there and used directly here.

Binary Heaps & Graphs as Data Structures

Two structures that look unrelated share a design philosophy: both maintain exactly as much information as their intended queries need, and no more.

A binary search tree maintains a total order, which is why it can answer any range query. A heap maintains only a partial order — every parent dominates its children, and nothing is known about siblings — which is why it cannot search but can produce the extreme element in constant time and restore itself in logarithmic time.

That deliberate weakness is what makes a heap cheap to maintain, and it is why a priority queue uses one rather than a search tree.

Graphs make a different version of the same trade, in the representation rather than the invariant. An adjacency matrix answers "is there an edge from to " in constant time and costs space. An adjacency list answers "what are 's neighbours" in time proportional to the degree and costs space.

Neither is better; density decides. A dense graph makes the matrix's space acceptable and its constant-time edge test valuable; a sparse graph makes the matrix mostly zeros and the list clearly superior.

1. The Heap Property

A binary heap is a complete binary tree — every level full except possibly the last, which fills from the left — satisfying a heap property.

In a max-heap, every node is greater than or equal to both its children. In a min-heap, every node is less than or equal to both.

Note what is not required. No relation is imposed between siblings, or between a node and its cousins. A heap is therefore far less ordered than a search tree, and that is deliberate: less order means less work to restore after a change.

Two immediate consequences are examined directly.

The root holds the extreme element, so finding the maximum in a max-heap is .

A heap cannot be searched efficiently. Locating an arbitrary key requires examining nodes, because the partial order gives no guidance about which subtree to descend into.

The inorder traversal of a heap is not sorted, unlike that of a BST, and no traversal of a heap produces sorted order without doing the work of a sort.

2. The Array Representation

Because a heap is a complete tree, it can be stored in an array with no pointers at all — the tree structure is implicit in the indices.

For 0-based indexing:

For 1-based indexing the formulas are cleaner:

The convention must be checked from the question, because the two give different answers for the same index.

Two counting facts follow from completeness.

The last internal node is at index in 0-based indexing, so everything from there onward is a leaf.

A heap of nodes has leaves, which is why building a heap can skip half the array entirely.

The array representation is what makes heapsort in-place and what makes a heap the standard priority queue implementation: no allocation, no pointers, and perfect cache behaviour on the upper levels.

3. Heap Operations

Two repair operations do all the work, and every heap operation is one of them applied after a structural change.

Sift-up (percolate up) repairs a node that is too large for its position. Compare with the parent, swap if the heap property is violated, and repeat upward. It costs because the path to the root has that length.

Sift-down (heapify) repairs a node that is too small. Compare with both children, swap with the larger, and repeat downward. It also costs .

OperationMethodCost
Find maximumRead the root
InsertAppend at the end, sift up
Extract maximumMove last to root, shrink, sift down
Increase a keyChange it, sift up
Delete a keyReplace with last, sift up or down
SearchLinear scan

Insertion appends at the first free position to preserve completeness, then sifts up. Extraction cannot simply remove the root, because that would break completeness, so the last element is moved to the root and sifted down.

4. Building a Heap

Given an arbitrary array, a heap can be built in two ways with different costs.

Inserting the elements one at a time costs , since each insertion can sift up through the full height.

Sifting down from the last internal node to the root costs , which is asymptotically better and is the standard method.

The surprising bound deserves its argument. Sift-down at a node costs time proportional to that node's height, not the tree's. Most nodes are near the bottom and have tiny height: half the nodes are leaves and cost nothing, a quarter have height 1, an eighth have height 2.

Summing height times count over all levels gives

because the series converges to a constant.

The intuition worth carrying is that the expensive nodes are rare. Only one node has the full height, and half the nodes have none at all.

5. Heapsort and Priority Queues

Heapsort builds a max-heap, then repeatedly swaps the root with the last element, shrinks the heap by one, and sifts down.

It runs in in all cases — best, average and worst — and sorts in place using only the original array plus a constant amount of extra space.

It is not stable, because sifting moves equal elements past each other unpredictably.

The comparison with quicksort and merge sort is the examined point. Quicksort is usually faster in practice despite an worst case, because its inner loop is tighter and its memory access is more local. Merge sort is stable and predictable but needs extra space. Heapsort is the one that guarantees in place, and it pays for that with poor cache behaviour, since sifting jumps across the array.

A priority queue is the heap's main application, supporting insert and extract-extreme in . It is the structure underneath Dijkstra's algorithm, Prim's algorithm, Huffman coding and event-driven simulation.

6. Graphs: Terminology and Counting

A graph is a set of vertices with a set of edges. The counting facts are asked directly.

An undirected simple graph on vertices has at most edges; a directed one has at most , since each ordered pair may have its own edge.

The sum of degrees is twice the edge count in an undirected graph, so the number of odd-degree vertices is even. In a directed graph, the sum of in-degrees equals the sum of out-degrees equals the edge count.

A graph is connected if a path exists between every pair. A directed graph is strongly connected if a directed path exists both ways between every pair, and weakly connected if the underlying undirected graph is connected.

A connected graph on vertices needs at least edges, achieved exactly by a tree, and a graph with vertices and more than edges must contain a cycle.

A graph with vertices and fewer than edges cannot be connected, which gives a fast elimination in many questions.

7. Graph Representations

PropertyAdjacency matrixAdjacency list
Space
Test edge
List neighbours of
Add an edge
SuitsDense graphsSparse graphs

The crossover is at . A graph is dense when the edge count approaches the maximum, and sparse when it is closer to .

Most real graphs — road networks, social graphs, web links — are sparse, which is why adjacency lists dominate in practice.

A useful matrix property is examined regularly: raising the adjacency matrix to the power gives, in entry , the number of distinct walks of length exactly from to .

For a weighted graph the matrix stores weights rather than 1s, with a sentinel such as infinity for absent edges, and the list stores pairs of neighbour and weight.

8. Traversals

Both traversals visit every reachable vertex once and cost the same.

Breadth-first search uses a queue and visits vertices in order of distance from the source. Depth-first search uses a stack, explicitly or through recursion, and goes as deep as possible before backtracking.

Both cost with an adjacency list and with a matrix, because listing a vertex's neighbours is what dominates.

Breadth-first search finds shortest paths in an unweighted graph, since it reaches every vertex by the fewest possible edges. It does not work for weighted graphs, which is exactly why Dijkstra's algorithm exists.

Depth-first search classifies each edge as it is explored, and the classification answers structural questions.

Edge typeMeaning
Tree edgeLeads to an unvisited vertex
Back edgeLeads to an ancestor on the current path
Forward edgeLeads to a descendant already finished
Cross edgeLeads elsewhere entirely

A directed graph has a cycle if and only if a depth-first search finds a back edge, which is the standard cycle-detection method and the basis of topological sorting.

In an undirected graph, only tree and back edges occur — forward and cross edges cannot arise, because an undirected edge to an already-visited vertex is always to an ancestor.

9. Worked Examples

Example 1. An array with 1-based indexing holds a max-heap. What are the indices of the parent, left child and right child of the element at index 7, in a heap of 20 elements?

With 1-based indexing, the parent of is , the left child is and the right child is .

Parent of 7: .

Left child: .

Right child: .

Both children exist because 14 and 15 are at most 20.

Under 0-based indexing the same element would sit at index 6, with parent , left child 13 and right child 14 — entirely different numbers for the same node, which is why the convention must be read from the question.

Example 2. Insert 45 into the max-heap [50, 30, 40, 10, 20, 35] using 0-based indexing. Show each swap.

Completeness requires appending at the first free position, index 6.

The array becomes [50, 30, 40, 10, 20, 35, 45].

Now sift up. The parent of index 6 is , holding 40. Since , swap.

Array: [50, 30, 45, 10, 20, 35, 40]. The new element is now at index 2.

The parent of index 2 is , holding 50. Since , the heap property holds and sifting stops.

The final heap is [50, 30, 45, 10, 20, 35, 40], after 2 comparisons and 1 swap.

Note that 45 ended above 30 despite 30 having been higher in the array, and no comparison between them ever occurred. That is the partial order at work: siblings and cousins are simply unrelated.

Example 3. Build a max-heap from [4, 10, 3, 5, 1] using the linear-time method, with 0-based indexing.

There are elements, so the last internal node is at index . Sift down from index 1 to index 0.

Index 1 holds 10, with children at indices 3 and 4 holding 5 and 1. The largest is 10 itself, so nothing moves.

Index 0 holds 4, with children at indices 1 and 2 holding 10 and 3. The largest child is 10, and , so swap.

Array: [10, 4, 3, 5, 1]. The value 4 is now at index 1.

Continue sifting 4 down. Its children are at indices 3 and 4, holding 5 and 1. The largest is 5, and , so swap.

Array: [10, 5, 3, 4, 1]. The value 4 is now at index 3, which is a leaf, so sifting stops.

The max-heap is [10, 5, 3, 4, 1].

Indices 2, 3 and 4 were never sifted from, which is exactly the saving: of the 5 nodes are leaves and are already valid heaps of one element.

Example 4. Why is building a heap rather than ?

The naive bound assumes every sift-down costs . It does not: a sift-down from a node costs time proportional to the height of that node, and most nodes are shallow.

In a heap of nodes, roughly are leaves with height 0, have height 1, have height 2, and so on, with exactly one node at the full height.

The total work is the sum over heights of the number of nodes at that height times the height:

The series converges to 2 as the upper limit grows, so the total is bounded by .

The insight is that the expensive nodes are rare. Only the root can cost the full , and the half of the array that costs nothing at all is skipped entirely.

Contrast this with inserting one at a time, which genuinely is : each insertion sifts up from a leaf position, and leaf positions are exactly where the path to the root is longest.

Example 5. A simple undirected graph has 8 vertices. What is the maximum number of edges, and what is the minimum number for it to be connected? If it has 10 edges, must it contain a cycle?

The maximum is one edge per unordered pair: edges.

The minimum for connectivity is edges, achieved exactly by a spanning tree.

For the cycle question, recall that a connected acyclic graph on vertices has exactly edges. Any graph with more than edges must contain a cycle, regardless of connectivity, because each connected component with vertices can hold at most edges without a cycle, and summing over components gives at most .

With 10 edges against a threshold of 7, the graph must contain a cycle — in fact at least 3 independent cycles, since the cycle count is where is the number of components, giving at least .

Example 6. A directed graph is searched depth-first and a back edge is found. What does this prove, and what would the absence of any back edge prove?

A back edge leads from the current vertex to an ancestor still on the recursion stack.

That ancestor reached the current vertex by a directed path of tree edges, and the back edge returns directly to it. Together they form a directed cycle, so the presence of a back edge proves the graph is cyclic.

The converse also holds. If a directed graph contains a cycle, then during the depth-first search the first vertex of that cycle to be discovered will still be on the stack when the cycle's last edge is explored, so that edge is classified as a back edge.

So a directed graph is acyclic if and only if a depth-first search finds no back edge, which is the standard cycle-detection method.

The absence of back edges therefore proves the graph is a directed acyclic graph, which in turn guarantees that a topological order exists — obtained by listing the vertices in reverse order of their depth-first finishing times.

Note that in an undirected graph the classification is simpler: only tree and back edges can occur, so a back edge to any vertex other than the immediate parent proves a cycle.

Summary

A heap maintains only a partial order — parent dominates children, siblings unrelated — which is why it cannot search but can restore itself in logarithmic time.

Completeness allows a pointerless array representation. Index formulas differ between 0-based and 1-based conventions, and the convention must be read from the question.

The last internal node is at in 0-based indexing, and of the nodes are leaves.

Every operation is a sift-up or a sift-down, each costing . Insertion appends then sifts up; extraction moves the last element to the root then sifts down.

Building a heap by sifting down from the last internal node costs , because sift-down cost is proportional to a node's height and most nodes are shallow. Inserting one at a time genuinely costs .

Heapsort is in all cases and in place, but is unstable and has poor cache behaviour.

An undirected simple graph on vertices has at most edges and needs at least to be connected. More than edges forces a cycle.

An adjacency matrix costs space with a constant-time edge test; an adjacency list costs with neighbour listing proportional to degree. Density decides.

The -th power of the adjacency matrix counts walks of length .

Breadth-first search uses a queue and gives shortest paths in unweighted graphs; depth-first search uses a stack and classifies edges. A directed graph is acyclic exactly when depth-first search finds no back edge, and undirected searches produce only tree and back edges.

Key formulas & results

Everything to memorise for the exam hall, in one card. Screenshot this for revision.

The organising tool
BOTH STRUCTURES MAINTAIN EXACTLY AS MUCH INFORMATION AS THEIR INTENDED QUERIES NEED, AND NO MORE.
A HEAP'S PARTIAL ORDER IS A DELIBERATE WEAKNESS THAT MAKES IT CHEAP TO RESTORE. A GRAPH REPRESENTATION BUYS EITHER FAST EDGE TESTING OR FAST NEIGHBOUR LISTING.
The heap property
A BINARY HEAP IS A COMPLETE BINARY TREE IN WHICH EVERY NODE DOMINATES ITS CHILDREN: GREATER OR EQUAL IN A MAX-HEAP, LESS OR EQUAL IN A MIN-HEAP.
NO RELATION IS IMPOSED BETWEEN SIBLINGS OR COUSINS. THE ROOT HOLDS THE EXTREME ELEMENT, SO FINDING IT IS CONSTANT TIME.
Why a heap cannot search
LOCATING AN ARBITRARY KEY REQUIRES EXAMINING O(n) NODES, BECAUSE THE PARTIAL ORDER GIVES NO GUIDANCE ABOUT WHICH SUBTREE TO DESCEND INTO.
THE INORDER TRAVERSAL OF A HEAP IS NOT SORTED, UNLIKE A BST, AND NO TRAVERSAL PRODUCES SORTED ORDER WITHOUT DOING THE WORK OF A SORT.
Index formulas, 0-based
left(i) = 2i PLUS 1, right(i) = 2i PLUS 2, parent(i) = FLOOR OF (i MINUS 1) OVER 2.
THE ARRAY REPRESENTATION NEEDS NO POINTERS BECAUSE COMPLETENESS MAKES THE TREE STRUCTURE IMPLICIT IN THE INDICES.
Index formulas, 1-based
left(i) = 2i, right(i) = 2i PLUS 1, parent(i) = FLOOR OF i OVER 2.
THE CONVENTION MUST BE CHECKED FROM THE QUESTION, BECAUSE THE TWO GIVE COMPLETELY DIFFERENT INDICES FOR THE SAME NODE.
Counting in a heap
IN 0-BASED INDEXING THE LAST INTERNAL NODE IS AT FLOOR OF n OVER 2, MINUS 1, AND A HEAP OF n NODES HAS CEILING OF n OVER 2 LEAVES.
EVERYTHING FROM THE LAST INTERNAL NODE ONWARD IS A LEAF, WHICH IS WHY BUILDING A HEAP CAN SKIP HALF THE ARRAY ENTIRELY.
The two repair operations
SIFT-UP COMPARES WITH THE PARENT AND SWAPS UPWARD; SIFT-DOWN COMPARES WITH BOTH CHILDREN, SWAPS WITH THE LARGER, AND REPEATS DOWNWARD. BOTH COST O(log n).
EVERY HEAP OPERATION IS ONE OF THESE TWO APPLIED AFTER A STRUCTURAL CHANGE, WHICH IS WHY THE WHOLE STRUCTURE HAS ONLY TWO PRIMITIVES.
Insertion and extraction
INSERTION APPENDS AT THE FIRST FREE POSITION AND SIFTS UP. EXTRACTION MOVES THE LAST ELEMENT TO THE ROOT, SHRINKS THE HEAP, AND SIFTS DOWN.
BOTH ARRANGEMENTS EXIST TO PRESERVE COMPLETENESS, SINCE SIMPLY REMOVING THE ROOT WOULD LEAVE A HOLE THAT BREAKS THE ARRAY REPRESENTATION.
Heap operation costs
FIND MAXIMUM IS CONSTANT. INSERT, EXTRACT, INCREASE-KEY AND DELETE ARE ALL LOGARITHMIC. SEARCH IS LINEAR.
THE LINEAR SEARCH COST IS THE PRICE OF THE PARTIAL ORDER AND IS WHY A HEAP IS NEVER USED WHERE ARBITRARY LOOKUP IS NEEDED.
Building a heap
SIFTING DOWN FROM THE LAST INTERNAL NODE TO THE ROOT COSTS O(n). INSERTING THE ELEMENTS ONE AT A TIME COSTS O(n log n).
SIFT-DOWN COST IS PROPORTIONAL TO A NODE'S HEIGHT, NOT THE TREE'S, AND MOST NODES ARE SHALLOW: HALF ARE LEAVES COSTING NOTHING.
The linear-time argument
T(n) = SUM OVER h OF (n OVER 2^(h+1)) TIMES h, WHICH IS O(n) BECAUSE THE SERIES h OVER 2^h CONVERGES TO 2.
ONLY THE ROOT CAN COST THE FULL log n, AND THE HALF OF THE ARRAY THAT COSTS NOTHING AT ALL IS SKIPPED ENTIRELY.
Heapsort
BUILD A MAX-HEAP, THEN REPEATEDLY SWAP THE ROOT WITH THE LAST ELEMENT, SHRINK BY ONE, AND SIFT DOWN. IT IS O(n log n) IN ALL CASES AND IN PLACE.
IT IS NOT STABLE, BECAUSE SIFTING MOVES EQUAL ELEMENTS PAST EACH OTHER, AND ITS CACHE BEHAVIOUR IS POOR BECAUSE SIFTING JUMPS ACROSS THE ARRAY.
Sorting comparison
QUICKSORT IS USUALLY FASTEST DESPITE AN O(n^2) WORST CASE. MERGE SORT IS STABLE BUT NEEDS LINEAR EXTRA SPACE. HEAPSORT GUARANTEES O(n log n) IN PLACE.
HEAPSORT'S GUARANTEE IS PAID FOR WITH POOR LOCALITY, WHICH IS WHY IT IS OFTEN SLOWER IN PRACTICE THAN AN ALGORITHM WITH A WORSE WORST CASE.
Priority queue applications
A PRIORITY QUEUE SUPPORTS INSERT AND EXTRACT-EXTREME IN LOGARITHMIC TIME AND IS THE STRUCTURE UNDER DIJKSTRA, PRIM, HUFFMAN CODING AND EVENT SIMULATION.
THIS IS THE HEAP'S MAIN APPLICATION AND THE REASON IT APPEARS IN THE ALGORITHMS CHAPTERS AS WELL AS THIS ONE.
Maximum edges
AN UNDIRECTED SIMPLE GRAPH ON n VERTICES HAS AT MOST C(n,2) = n(n-1)/2 EDGES; A DIRECTED ONE HAS AT MOST n(n-1).
THE DIRECTED BOUND IS TWICE THE UNDIRECTED ONE BECAUSE EACH ORDERED PAIR MAY CARRY ITS OWN EDGE.
Degree sums
IN AN UNDIRECTED GRAPH THE SUM OF DEGREES IS TWICE THE EDGE COUNT, SO THE NUMBER OF ODD-DEGREE VERTICES IS EVEN. IN A DIRECTED GRAPH, IN-DEGREE SUM EQUALS OUT-DEGREE SUM EQUALS THE EDGE COUNT.
THE PARITY CONSEQUENCE ALONE ELIMINATES MANY OPTIONS IN DEGREE-SEQUENCE QUESTIONS.
Connectivity thresholds
A CONNECTED GRAPH ON n VERTICES NEEDS AT LEAST n MINUS 1 EDGES, ACHIEVED EXACTLY BY A TREE. MORE THAN n MINUS 1 EDGES FORCES A CYCLE.
FEWER THAN n MINUS 1 EDGES CANNOT BE CONNECTED, WHICH GIVES A FAST ELIMINATION. THE INDEPENDENT CYCLE COUNT IS E MINUS V PLUS C.
Strong versus weak connectivity
A DIRECTED GRAPH IS STRONGLY CONNECTED IF A DIRECTED PATH EXISTS BOTH WAYS BETWEEN EVERY PAIR, AND WEAKLY CONNECTED IF THE UNDERLYING UNDIRECTED GRAPH IS CONNECTED.
STRONG CONNECTIVITY IS THE STRICTER CONDITION, AND A WEAKLY CONNECTED GRAPH MAY HAVE VERTICES THAT CANNOT REACH EACH OTHER AT ALL.
Representation trade-off
A MATRIX COSTS O(V^2) SPACE WITH A CONSTANT-TIME EDGE TEST AND O(V) NEIGHBOUR LISTING. A LIST COSTS O(V + E) SPACE WITH DEGREE-TIME EDGE TESTING AND NEIGHBOUR LISTING.
THE CROSSOVER IS WHERE E APPROACHES V SQUARED. MOST REAL GRAPHS ARE SPARSE, WHICH IS WHY ADJACENCY LISTS DOMINATE IN PRACTICE.
Matrix powers
THE (i,j) ENTRY OF THE k-TH POWER OF THE ADJACENCY MATRIX IS THE NUMBER OF DISTINCT WALKS OF LENGTH EXACTLY k FROM i TO j.
WALKS MAY REPEAT VERTICES AND EDGES, SO THIS COUNTS MORE THAN PATHS. IT IS ASKED DIRECTLY AND IS COMPUTED BY REPEATED MATRIX MULTIPLICATION.
Traversal costs
BREADTH-FIRST AND DEPTH-FIRST SEARCH BOTH COST O(V + E) WITH AN ADJACENCY LIST AND O(V^2) WITH A MATRIX.
THE DIFFERENCE COMES ENTIRELY FROM HOW LONG IT TAKES TO LIST A VERTEX'S NEIGHBOURS, WHICH IS WHAT DOMINATES BOTH TRAVERSALS.
Breadth-first shortest paths
BREADTH-FIRST SEARCH USES A QUEUE AND VISITS VERTICES IN ORDER OF DISTANCE, SO IT FINDS SHORTEST PATHS IN AN UNWEIGHTED GRAPH.
IT FAILS ON WEIGHTED GRAPHS BECAUSE FEWER EDGES NEED NOT MEAN LESS WEIGHT, WHICH IS EXACTLY WHY DIJKSTRA'S ALGORITHM EXISTS.
Edge classification
TREE EDGES REACH UNVISITED VERTICES, BACK EDGES REACH ANCESTORS ON THE CURRENT PATH, FORWARD EDGES REACH FINISHED DESCENDANTS, AND CROSS EDGES REACH ELSEWHERE.
IN AN UNDIRECTED GRAPH ONLY TREE AND BACK EDGES OCCUR, BECAUSE AN EDGE TO AN ALREADY-VISITED VERTEX IS ALWAYS TO AN ANCESTOR.
Cycle detection
A DIRECTED GRAPH HAS A CYCLE IF AND ONLY IF A DEPTH-FIRST SEARCH FINDS A BACK EDGE.
THE ABSENCE OF BACK EDGES PROVES THE GRAPH IS ACYCLIC AND THEREFORE HAS A TOPOLOGICAL ORDER, OBTAINED BY REVERSE FINISHING TIME.
⚠️

Traps GATE sets — and how to dodge them

These are the exact option-traps and misreads that cost marks under negative marking.

WATCH OUT
Using the wrong index convention for heap children
0-based gives children at 2i+1 and 2i+2; 1-based gives 2i and 2i+1. The same node has different indices under the two, so the convention must be read from the question before computing anything.
WATCH OUT
Assuming a heap's inorder traversal is sorted
That property belongs to a binary search tree. A heap constrains only parent against child, so siblings and cousins are unrelated and no traversal produces sorted order without a full sort.
WATCH OUT
Expecting to search a heap in logarithmic time
The partial order gives no guidance about which subtree holds a given key, so search is linear. A heap is never the right structure when arbitrary lookup is required.
WATCH OUT
Removing the root directly on extraction
That leaves a hole and breaks completeness, which the array representation depends on. The last element is moved to the root, the heap shrinks by one, and a sift-down restores the property.
WATCH OUT
Claiming build-heap costs n log n
Sift-down cost is proportional to the node's height, not the tree's, and half the nodes are leaves with height zero. Summing height times count gives a convergent series and a linear total.
WATCH OUT
Confusing build-by-sift-down with build-by-insertion
Repeated insertion genuinely costs n log n, because each new element sifts up from a leaf position where the path to the root is longest. Only the sift-down method achieves linear time.
WATCH OUT
Assuming heapsort is stable
Sifting moves equal elements past each other unpredictably, so relative order is not preserved. Merge sort is the stable comparison sort with a guaranteed bound, at the cost of linear extra space.
WATCH OUT
Assuming heapsort is fastest because its worst case is best
Quicksort is usually faster in practice despite a quadratic worst case, because sifting jumps across the array and defeats the cache while quicksort's partition scans are sequential.
WATCH OUT
Using the undirected edge bound for a directed graph
A directed simple graph allows an edge in each direction between a pair, so the maximum is n(n-1), exactly twice the undirected bound of n(n-1)/2.
WATCH OUT
Confusing strong with weak connectivity
Strong connectivity requires a directed path both ways between every pair. A weakly connected graph only requires the underlying undirected graph to be connected, so vertices may be mutually unreachable.
WATCH OUT
Choosing an adjacency matrix for a sparse graph
The matrix costs V squared space regardless of edge count, so a sparse graph wastes almost all of it on zeros. Lists cost V plus E and are the right choice unless the graph is genuinely dense.
WATCH OUT
Reading matrix powers as counting paths
They count walks, which may repeat vertices and edges. A walk of length 3 from a vertex back to itself and out again is counted, even though it is not a simple path.
WATCH OUT
Using breadth-first search for weighted shortest paths
It minimises the number of edges, not the total weight, so a two-edge path of weight 10 beats a one-edge path of weight 100 and breadth-first search picks the wrong one. Dijkstra's algorithm exists for exactly this.
WATCH OUT
Expecting forward and cross edges in an undirected search
Only tree and back edges occur. Any edge to an already-visited vertex must lead to an ancestor, because an undirected edge would have been explored from the other end if it led elsewhere.

Exam-pattern practice

PYQ-style questions with full solutions. Work through them as a readiness check — mark yourself honestly and get your gap report at the end.

Readiness check

Are you exam-ready for Binary Heaps & Graphs as Data Structures?

9 problems from this chapter. Try each one, reveal the worked solution, mark yourself honestly — get your gap report at the end.

9 questions~6 min

5-minute revision

The whole chapter, distilled. Read this the night before the exam.

  • A heap keeps only a partial order.
  • Siblings and cousins are unrelated.
  • The root holds the extreme element.
  • Heap search is linear.
  • A heap's inorder traversal is not sorted.
  • 0-based children are 2i+1 and 2i+2.
  • 1-based children are 2i and 2i+1.
  • Check the indexing convention first.
  • The last internal node is at floor(n/2) minus 1.
  • A heap of n nodes has ceil(n/2) leaves.
  • Sift-up and sift-down each cost log n.
  • Insertion appends then sifts up.
  • Extraction moves the last element to the root.
  • Build-heap by sift-down costs O(n).
  • Build by repeated insertion costs O(n log n).
  • Sift-down cost is the node's height, not the tree's.
  • Heapsort is O(n log n) in all cases and in place.
  • Heapsort is not stable.
  • Heapsort has poor cache locality.
  • A priority queue underlies Dijkstra, Prim and Huffman.
  • Undirected maximum edges is n(n-1)/2.
  • Directed maximum edges is n(n-1).
  • Degree sum is twice the edge count.
  • Odd-degree vertices are even in number.
  • Connectivity needs at least n-1 edges.
  • More than n-1 edges forces a cycle.
  • Independent cycles number E minus V plus C.
  • Strong connectivity needs directed paths both ways.
  • A matrix costs V squared space.
  • A list costs V plus E space.
  • Density decides the representation.
  • Matrix powers count walks, not paths.
  • Both traversals cost V plus E with a list.
  • Breadth-first search gives unweighted shortest paths.
  • Breadth-first search fails on weighted graphs.
  • A back edge proves a directed cycle.
  • No back edge means a topological order exists.
  • Undirected searches produce only tree and back edges.

GATE question blueprint

How this topic is asked, tier by tier — so you can prep to the pattern.

Typical weightage: Programming & Data Structures contributes roughly 8-10 of the 72 core-CS marks; heaps and graph representations supply 2-3 of those across 2-3 questions

Question styleMarks eachTypical countWhat it tests
Heap indexing1~1Parent and child formulas under both conventions
Heap operations1~1Costs of each operation and why search is linear
Heap construction2~1Tracing sift-downs from the last internal node
Build-heap analysis2~1The linear-time argument and the contrast with repeated insertion
Graph counting2~1Edge bounds, connectivity thresholds and independent cycle counts
Graph representations2~1Space and query comparison and the density crossover
Traversals2~1Costs under each representation and why breadth-first fails on weights
Cycle detection2~1The back-edge equivalence and topological ordering

Exam-hall strategy

Battle-tested tips from mentors and toppers for this topic under the sectional clock.

  1. Read the indexing convention before computing any heap index.
  2. For build-heap questions, start at the last internal node and skip the leaves.
  3. Quote build-heap as O(n) and repeated insertion as O(n log n); the distinction is the question.
  4. For representation questions, compare E against V squared to decide density.
  5. For traversal costs, state whether the representation is a list or a matrix.
  6. For cycle questions, look for a back edge rather than trying to trace the cycle.
  7. Heap indices and edge counts are commonly set as NAT, which carries no negative marking, so never leave one blank.
  8. For 1-mark and 2-mark MCQs, negative marking is -1/3 and -2/3, so guess only after eliminating an option.
  9. GATE gives a single freely-navigable 180-minute window, so flag a long heap construction and return to it.

Beyond the exam

Where this skill shows up in the job you're competing for — and in life.

A task scheduler

A priority queue built on a heap is what lets a scheduler always pick the highest-priority runnable task in logarithmic time as tasks arrive and complete.

Event-driven simulation

Pending events are held in a min-heap keyed on time, so the next event to occur is always available at the root and new events insert cheaply.

Detecting a dependency cycle

A build system runs a depth-first search over the dependency graph and reports a back edge as a circular dependency, which is exactly the cycle test here.

Choosing a graph representation

Road networks and social graphs are sparse, which is why routing and recommendation systems store adjacency lists rather than matrices.

Where else this topic is tested

Prepare once, score in every exam that asks it.

GATE DAModerate overlap — heaps and graph traversals appear, with more emphasis on their use inside machine-learning pipelines
UGC NET Computer ScienceHigh overlap — heap properties, graph representations and traversal costs are examined as direct recall
ISRO / BARC / DRDO computer science papersVery high overlap — heap index arithmetic, build-heap cost and edge counting are recurring MCQ topics

Questions aspirants ask

Pulled from the Q&A community and mentor sessions.

Because the order it omits is order it would have to pay to maintain, and its intended queries do not need it. A binary search tree maintains a total order, so every key's position relative to every other is determined, and that is what lets it answer range queries and find arbitrary keys in logarithmic time. The price is that an insertion or deletion can disturb the ordering across a whole path and, in a balanced tree, trigger rotations to keep the height logarithmic. A heap needs only one query answered cheaply: give me the extreme element. Maintaining just the parent-dominates-child relation is sufficient for that, since the root must then dominate everything. Nothing constrains siblings or cousins, so a change disturbs only a single root-to-leaf path and is repaired by one sift-up or sift-down with no rotations and no rebalancing. The cost of the weakness is exactly what you would expect: search becomes linear, because the partial order gives no guidance about which subtree to descend into, and no traversal produces sorted order. That is an acceptable trade for a priority queue, where the only operations are insert and extract-extreme. It is unacceptable for a dictionary, which is why the two structures coexist rather than one replacing the other. The general lesson generalises well beyond heaps: a data structure is fast because of what it declines to know.

Because the logarithmic bound applies to the tree's height, not to each node's, and most nodes sit near the bottom where their own height is tiny. A sift-down starting at a node can only descend as far as the subtree beneath it extends, so its cost is proportional to that node's height. In a heap of n nodes, about half are leaves with height zero and cost nothing at all — which is why the build procedure starts at the last internal node and skips them entirely. A quarter of the nodes have height one and cost at most one swap. An eighth have height two. Exactly one node, the root, has the full height and costs the full logarithm. Summing height times count across all levels gives n over two, multiplied by the sum of h over two to the h. That series converges to two, so the total is bounded by n. The picture to carry is that the expensive operations are rare and the cheap ones are numerous, and the two effects multiply out to a constant. Repeated insertion behaves oppositely and genuinely costs n log n. Each inserted element enters at a leaf position and sifts upward, and a leaf is precisely where the path to the root is longest. So the costs do not decay; most insertions pay near the full height, and summing gives n log n with a tight bound.

By asking how dense the graph is and which query dominates. The matrix costs V squared space unconditionally, so for a graph with 1000 vertices it allocates a million entries whether there are 3000 edges or 400,000. The list costs V plus E, which for the same 1000 vertices and 3000 undirected edges is about 7000 entries. When the edge count is far below the maximum, the matrix is almost entirely zeros and the list wins by orders of magnitude in space. The query costs then point in opposite directions. Testing whether a specific edge exists is a single lookup in a matrix, and a scan of one vertex's neighbour list otherwise, costing time proportional to its degree. Listing a vertex's neighbours is degree time with a list, and a full row scan of V entries with a matrix even when the vertex has two neighbours. Since traversals, shortest-path algorithms and spanning-tree algorithms all iterate over neighbours rather than testing arbitrary edges, the list is the right default and is why both breadth-first and depth-first search cost V plus E with a list and V squared with a matrix. The matrix earns its place when the graph is genuinely dense, when edge existence is queried far more often than neighbours are enumerated, or when the algorithm needs matrix operations directly — such as raising the matrix to a power to count walks.

Because it minimises the number of edges on a path, and only in an unweighted graph is that the same thing as minimising the total cost. The search maintains a queue and processes vertices strictly in discovery order. Every vertex at distance k is enqueued before any at distance k plus 1, so the frontier expands one full layer at a time. The first time a vertex is reached, it has been reached by the fewest possible edges, and recording the discovering edge builds a shortest-path tree at total cost V plus E. In a weighted graph the equivalence breaks. Consider three vertices with a direct edge of weight 100 from the source to the target, and a two-edge route through an intermediate vertex with weights 1 and 1. Breadth-first search reaches the target in one layer via the expensive edge, finalises it, and reports cost 100, while the genuine shortest path costs 2 but sits one layer deeper. Nothing about the queue lets the search reconsider. The repair is to finalise vertices in order of accumulated weight rather than edge count, which is exactly what Dijkstra's algorithm does by replacing the queue with a priority queue. That is the direct link between the two halves of this chapter: the heap is what makes the priority queue efficient, and therefore what makes weighted shortest paths tractable at V plus E log V rather than something worse.

A back edge proves a directed cycle, and the equivalence runs in both directions. If a back edge exists, it leads from the vertex currently being explored to an ancestor still on the recursion stack. That ancestor reached the current vertex through a chain of tree edges, so following the chain and then the back edge closes a directed cycle. Conversely, if a cycle exists, consider the first of its vertices that the search discovers. Every other vertex on the cycle is reachable from it along the cycle, so all of them become its descendants, and in particular its predecessor on the cycle finishes while it is still on the stack. The edge from that predecessor back to it is therefore classified as a back edge. So a directed graph is acyclic exactly when the search finds no back edge, which gives an O(V + E) test and, as a bonus, a topological order by reverse finishing time. In an undirected graph the four-way classification collapses to two. Suppose the search is at vertex u and examines an edge to an already-visited vertex v. If v were neither an ancestor nor a descendant, then when v was being explored it would have examined the same edge from its own end and discovered u at that time, contradicting the assumption that u was unvisited. So v must be an ancestor, and the edge is a back edge. Forward and cross edges cannot arise, and the only care needed is to ignore the edge back to the immediate parent, which is the same undirected edge seen from the other side.
Header Logo