Everything on the site.

Big-O notationAlgorithms · Count the steps in real loops, then compare n, n log n, n² and 2ⁿ on a live chart.RecursionAlgorithms · Watch frames push and pop on the call stack for factorial and Fibonacci.BFS vs DFSAlgorithms · A queue against a stack: draw a graph and see which order each search visits it in.Sorting algorithmsAlgorithms · Seven sorts on the same input, with comparison, swap and write counts side by side.Binary searchAlgorithms · Halve the range, probe the middle, repeat: with lo, mid and hi drawn on the array.Sets, relations and functionsDiscrete maths · Shade any set expression on a Venn diagram and test a relation for its properties.Proof by inductionDiscrete maths · Four worked proofs revealed one step at a time, and a broken one to diagnose.CombinatoricsDiscrete maths · An exact nPr and nCr calculator, and a Pascal’s triangle that shows its own addition rule.Boolean algebraDiscrete maths · The laws, De Morgan, and normal forms, with a truth-table generator built in.Finite-state machinesTheory · Build a DFA in a table, see it drawn, and run strings through it one symbol at a time.Domain theoryTheory · Why recursion needs least fixed points, and how CPOs, Scott continuity and powerdomains supply them.Truth table generatorTools · Expression in, truth table out: with DNF, CNF, a minimal form and LaTeX.Graph traversal visualiserTools · Draw a graph, then animate BFS, DFS and Dijkstra with the frontier shown.Recursion tree visualiserTools · Paste a recursive function or a recurrence and see its call tree and call count.Gradient descentML maths · Drag the starting point, set the learning rate, and watch it converge or blow up.Vectors and embeddingsML maths · Bend the plane with a 2×2 matrix and measure how close toy word vectors are.Softmax and cross-entropyML maths · Edit the logits and watch the probabilities, the loss and the gradient update live.Attention mechanismML maths · Q, K and V for three tokens, a live score heatmap, and the weighted sum of values.Formatting a CS paper in LaTeXLaTeX · Page limits, \documentclass, front matter, theorem environments and the bibliography.Camera-ready checklistLaTeX · Fonts embedded, PDF/A, copyright form, source bundle, and why final versions get rejected.LaTeX templatesLaTeX · Where the official classes live, plus a minimal article template you can copy.Boolean algebra calculatorTools · A Boolean expression simplifier that names the law used at every step.K-map solverTools · Fill in a Karnaugh map and see the groups, the minimal SOP and POS, and the essential terms.Logic gate simulatorTools · Wire up gates, flip the switches, and get the truth table and expression of your circuit.Regex to NFA converterTools · Type a regular expression and watch Thompson’s construction build its NFA, fragment by fragment.NFA to DFA converterTools · Enter an NFA or a regex and step through the subset construction, then minimise the DFA.DFA simulatorTools · Edit a DFA, run strings through it step by step, batch-test them and share the machine as a link.Regular expressions to automataTheory · Regex to NFA to DFA to minimal DFA, worked through on one example with every set shown.The halting problemTheory · Why no program can tell whether every program halts, with the paradox program played out.Pigeonhole principleDiscrete maths · n pigeons, k holes: why some hole gets ⌈n/k⌉, and the surprising things that follows from it.Dijkstra’s algorithmAlgorithms · Shortest paths with a priority queue: a worked table, a proof, and a graph you can redraw.Hash functionsAlgorithms · Keys in, buckets out: hash a word four ways, then watch chaining and probing handle collisions.Sorting algorithm visualizerTools · Up to seven sorts race on the same data, then step through any one of them line by line.LaTeX table generatorTools · Type or paste a table, merge cells, pick booktabs, and copy clean tabular code.Combination calculatorTools · Exact nCr with the cancelling shown, combinations with repetition, and a full list for small n.Permutation calculatorTools · nPr, nʳ, anagrams like MISSISSIPPI and round-table seatings, with exact working.AlgorithmsSection · Step-through visualisations of sorting, searching, recursion, graph traversal, Dijkstra’s algorithm, hash functions and Big-O growth, with pseudocode that follows along.Discrete mathsSection · Sets, relations and functions, proof by induction, counting, the pigeonhole principle and Boolean algebra, explained with worked examples and interactive checkers.TheorySection · Finite-state machines, regular expressions and automata, the halting problem, and the mathematical semantics of programming languages, explained from first principles.ML mathsSection · Gradient descent, vectors and embeddings, softmax and cross-entropy, and attention, each with a formula, a worked numeric example and a live version.ToolsSection · Free browser tools: truth tables, Boolean simplification, K-maps, logic gates, nCr and nPr, regex to NFA to DFA, sorting and graph visualisers, and LaTeX tables.LaTeXSection · How to format a CS conference or workshop paper in LaTeX, a camera-ready checklist, and a minimal template you can adapt.
Algorithms

Dijkstra’s algorithm explained step by step

Dijkstra’s algorithm finds the shortest path from one starting point to every other point in a graph whose edges have non-negative weights: road distances, network delays, travel times. This page works through it by hand, then lets you run it step by step on a graph you can redraw yourself.

Interactive: Step-through Dijkstra on a drawable weighted graphUpdated

The problem

You have a weighted graph: vertices joined by edges, each edge carrying a length or cost w(u,v)≥0w(u, v) \ge 0. The length of a path is the sum of its edge weights. Given a source vertex ss, the single-source shortest-path problem asks for the shortest distance δ(s,v)\delta(s, v) to every vertex vv, and a path that achieves it.

If every edge had weight 1, breadth-first search would solve this: it visits vertices in order of their number of edges from ss. Dijkstra’s algorithm, published by Edsger Dijkstra in 1959, generalises BFS to weighted edges. It replaces BFS’s first-in, first-out queue with a priority queue that always hands back the closest vertex not yet finished.

The idea in one paragraph

Keep a tentative distance d[v]d[v] for every vertex, starting at 0 for the source and ∞\infty for everything else. Repeatedly pick the unfinished vertex with the smallest tentative distance and declare that distance final: the vertex is settled. Then relax each edge leaving it: if going through uu gives a neighbour vv a shorter route than any known so far, lower d[v]d[v] and remember uu as vv’s parent:

if d[u]+w(u,v)<d[v]:d[v]←d[u]+w(u,v),parent[v]←u.\text{if } d[u] + w(u, v) < d[v]: \quad d[v] \leftarrow d[u] + w(u, v), \quad \text{parent}[v] \leftarrow u.

When every reachable vertex is settled, dd holds the shortest distances, and the parent pointers form a shortest-path tree.

Try it

The visualiser opens on a small road map, searching from S. Step forwards with → and watch the priority queue, the distance table and the highlighted pseudocode. Then drag vertices, change weights or draw your own graph; the run restarts automatically.

Dijkstra’s algorithm, step by stepDraw your own graph or start from a preset, then pick an algorithm and a start vertex.

Drag vertices to move them. Click a vertex or edge to edit it.
  • Current vertex
  • Discovered / in the frontier
  • Finished (settled)
  • Edge skipped
Edit the graph as text

One edge per line: A B 4 joins A and B with weight 4 (weight optional, default 1). A line with one name adds a lone vertex.

Pseudocode

    Frontier

    Visit order

    Pseudocode

    This is the version most real programs use, with a binary-heap priority queue and “lazy deletion”: when a vertex’s distance improves, a new entry is pushed, and outdated entries are skipped when they come out.

    dijkstra(G, s):
        for each vertex v: d[v] ← ∞; parent[v] ← none
        d[s] ← 0
        PQ ← min-priority queue containing (0, s)
        while PQ is not empty:
            (dist, u) ← extract-min(PQ)
            if u is settled: continue        // a stale entry
            mark u settled
            for each edge (u, v) with weight w:
                if d[u] + w < d[v]:
                    d[v] ← d[u] + w
                    parent[v] ← u
                    insert (d[v], v) into PQ
        return d, parent

    Worked example: shortest paths from S

    The road map has edges S–A 7, S–B 2, A–B 3, A–C 4, B–D 8, B–C 9, C–D 1, C–T 5, D–T 3. Each row below is one round: the vertex settled in that round, then every tentative distance after its edges have been relaxed. Settled distances are in bold; they never change again.

    RoundSettleSABCDT
    1S (0)072∞∞∞
    2B (2)0521110∞
    3A (5)052910∞
    4C (9)05291014
    5D (10)05291013
    6T (13)05291013

    Three moments are worth following in the visualiser:

    • Round 2, A improves. The direct road S–A costs 7, but once B is settled at 2, the road B–A gives 2+3=52 + 3 = 5. The tentative 7 was never final; relaxing an edge is exactly how such detours are discovered.
    • D ties. D is reached at 10 through B (2 + 8) and again at 10 through C (9 + 1). A tie is not an improvement, so D keeps B as its parent. Both routes are shortest.
    • T is settled last. The shortest route to T is S → B → D → T, of length 13, found by following parent pointers back from T.

    Rebuilding the path

    Dijkstra’s algorithm records only one parent per vertex, but that is enough to recover every shortest path. To find the route to tt, start at tt, follow parent back to the source, and reverse the list. This costs time proportional to the number of edges on the path. If you only need the route to a single target, you can stop the main loop as soon as the target is settled; its distance is already final at that point.

    Why it is correct

    The whole algorithm rests on one claim: when a vertex is taken from the queue, its tentative distance is already the true shortest distance. Here is why, using the fact that weights are non-negative.

    Proof sketch: settled distances are final

    Claim: when uu is extracted and settled, d[u]=δ(s,u)d[u] = \delta(s, u).

    1. Tentative distances never undershoot: d[v]≥δ(s,v)d[v] \ge \delta(s, v) for every vv at all times, because each finite d[v]d[v] is the length of a real path that the algorithm has found.
    2. Suppose, for a contradiction, that uu is the first vertex settled with d[u]>δ(s,u)d[u] > \delta(s, u). Take a true shortest path from ss to uu.
    3. That path starts inside the settled set (at ss) and ends outside it (at uu), so it has a first vertex yy outside the set, entered from a settled vertex xx.
    4. xx was settled correctly, since uu is the first mistake, and when xx was settled the edge (x,y)(x, y) was relaxed. So d[y]≤δ(s,x)+w(x,y)=δ(s,y)d[y] \le \delta(s, x) + w(x, y) = \delta(s, y), which means d[y]=δ(s,y)d[y] = \delta(s, y).
    5. Because weights are non-negative, the rest of the path from yy to uu cannot have negative length, so δ(s,y)≤δ(s,u)<d[u]\delta(s, y) \le \delta(s, u) < d[u].
    6. Then d[y]<d[u]d[y] < d[u], yet the algorithm extracted uu as the smallest. Contradiction: no such uu exists, so every settled distance is correct.

    As a corollary, vertices are settled in non-decreasing order of distance, as the “Settle” column of the worked example shows: 0, 2, 5, 9, 10, 13.

    Negative edges break it

    The proof used non-negative weights in one place: the step that says the rest of the path cannot be shorter than nothing. With a negative edge, a vertex can be settled too early. In this directed graph the edges are S → A (2), S → B (4), B → A (-3), A → C (2).

    VertexSABC
    Dijkstra reports0244
    True distance0143

    Dijkstra settles A at 2 straight away, because 2 is the smallest tentative distance. Only later does it settle B and see the edge B → A, which gives 4−3=14 - 3 = 1. A is already settled, so the improvement is ignored, and C inherits the error. You can reproduce this in the visualiser: tick “Directed”, enter the edges as text, and it will warn you about the negative weight.

    For graphs with negative edges, use the Bellman–Ford algorithm. It relaxes every edge V−1V - 1 times, in O(VE)O(VE) time, and can also detect a negative cycle, a loop with negative total weight, around which there is no shortest path at all. In many applications, though, negative weights never arise: distances, times and costs are non-negative by nature.

    Running time

    Every vertex is settled once, and every edge is relaxed at most once in each direction. What changes is how the priority queue is implemented:

    Priority queueExtract-minInsert / decreaseTotalBest for
    Unsorted arrayO(V)O(V)O(1)O(1)O(V2)O(V^2)Dense graphs, E≈V2E \approx V^2
    Binary heapO(log⁡V)O(\log V)O(log⁡V)O(\log V)O((V+E)log⁡V)O((V + E)\log V)Sparse graphs, the usual choice
    Fibonacci heapO(log⁡V)O(\log V) amortisedO(1)O(1) amortisedO(E+Vlog⁡V)O(E + V\log V)Theory; rarely faster in practice

    With lazy deletion the heap can hold up to EE entries rather than VV, but since log⁡E≤2log⁡V\log E \le 2\log V the bound is the same. On the road map, the algorithm made 9 insertions and 9 extractions for 6 vertices and 9 edges. Road networks and most real graphs are sparse, which is why the binary-heap version is the standard one.

    Dijkstra, A* and friends

    • BFS is Dijkstra with every weight equal to 1, where a plain queue already delivers vertices in distance order.
    • A* search adds a heuristic h(v)h(v), an estimate of the remaining distance to the target, and orders the queue by d[v]+h(v)d[v] + h(v) instead of d[v]d[v]. With a heuristic that never overestimates, such as straight-line distance on a map, it still finds the shortest path but explores far fewer vertices. Dijkstra is A* with h=0h = 0.
    • Prim’s algorithm for minimum spanning trees has almost identical code; it keys the queue by the weight of the single connecting edge rather than the total distance from the source.
    • Route planners run Dijkstra-based algorithms on graphs with millions of vertices, with precomputation such as contraction hierarchies so a query touches only a tiny part of the map.
    Common mistakes Settling a vertex when it is inserted rather than when it is extracted; forgetting to skip stale queue entries, which settles a vertex twice; and running Dijkstra on a graph with negative edges. In the visualiser, watch for “stale entry” in the narration: that is the second guard doing its job.

    References

    1. E. W. Dijkstra, “A note on two problems in connexion with graphs”, Numerische Mathematik 1, 269–271, 1959. doi:10.1007/BF01386390
    2. M. L. Fredman and R. E. Tarjan, “Fibonacci heaps and their uses in improved network optimization algorithms”, Journal of the ACM 34(3), 1987. doi:10.1145/28869.28874
    3. P. E. Hart, N. J. Nilsson and B. Raphael, “A formal basis for the heuristic determination of minimum cost paths”, IEEE Transactions on Systems Science and Cybernetics 4(2), 1968. doi:10.1109/TSSC.1968.300136
    4. T. H. Cormen, C. E. Leiserson, R. L. Rivest and C. Stein, Introduction to Algorithms, 4th ed., MIT Press, 2022. Chapter 22, “Single-source shortest paths”.