Birthday probability for hash outputs 2026-10-13
How soon should a hash collision appear? Specify the probability distribution of the outputs first. Evaluate distinct keys and assume their hash values are independent random variables, each with the uniform distribution on a finite set of possible outputs. The randomness may come from an idealized randomly chosen hash function; a fixed hash function and a fixed list of keys have a definite outcome. Sampling the same key twice creates a repeated hash value without creating a hash collision, so distinctness of the queried keys matters.
This is the existing birthday problem, with hash values in place of birthdays. Let be the probability of at least one equal pair. The exact formula isThe empty product is , so . Given previous distinct hash values, the next value avoids them with conditional probability . Multiply these conditional chances and subtract from . Equivalently, for , exactly of the equally likely ordered outcomes have no repeated value. This derivation also explains why independence of all outputs, rather than merely uniform individual values, is required.[ref]
https://cacr.uwaterloo.ca/hac/about/chap2.pdf. Menezes, van Oorschot and Vanstone, Handbook of Applied Cryptography, section 2.1.5, Fact 2.27(i), birthday probability
For , the exact hash collision probabilities are , , and . Thus only distinct queries already exceed a one-half chance of some pair matching. The striking feature is the number of opportunities: queries supply pairs. By linearity of expectation, the expected value of the number of equal pairs is . This expectation counts pairs, not the probability of at least one pair; three equal outputs contribute three pairs in one outcome. The union bound gives .
Using the natural logarithm expansion in the exact product givesFor , the omitted correction in the logarithm of the no-collision probability is . Thus the approximation is controlled when is small; in particular it becomes accurate at the birthday scale proportional to as increases. The inequality also shows that the displayed approximation is a lower bound for when . Setting its exponent to gives the approximate half-probability sample size for large .
For comparison, under the same independent uniform model the probability of hitting one previously fixed digest in queries isEach query supplies one chance to hit , instead of a growing number of possible pairs. For , , and the first integer with is . In a toy model with possible -bit digests, the any-pair transition therefore has scale queries, while the fixed-target transition has scale . This explains the birthday-search distinction between collision resistance and preimage resistance.[ref]
https://cacr.uwaterloo.ca/hac/about/chap9.pdf. Menezes, van Oorschot and Vanstone, Handbook of Applied Cryptography, Fact 9.33 and section 9.7.1, generic collision versus preimage searches
The assumptions are essential. Uniform marginals alone do not give the product formula: if all equal one shared uniform random variable, every distinct pair collides with probability . A universal hash family bounds each pair's hash collision probability, but that condition alone does not supply joint independence of every output. Nor does a fixed output length establish collision resistance or preimage resistance: the toy has , making deliberate hash collisions immediate. The curves describe the specified model and do not establish the security of a concrete cryptographic hash function.
Birthday problem Created 2026-10-13 Updated 2026-10-14
The birthday problem asks for the probability that at least two members of a group share a birthday. Use the explicit model of independent random variables taking labels with a uniform distribution on a finite set. Let and be integers. For calendar examples below, stipulate equally likely labels and omit leap days. For , the probability of at least one matching pair isAt , the empty product is one and . At , a repeat is certain by the pigeonhole principle. Count the complement to obtain the formula: the first label has choices, then a distinct second label has , and so forth, out of equally likely label sequences.[ref]
For the stipulated calendar, and . Only 23 people suffice to put the probability above one half. There are possible pairs, each with matching probability . The many comparison opportunities explain why a small group can contain a repeat.
The distinction also matters for hash collisions. If independently generated outputs of a hash function are uniformly distributed over possible labels, the same counting formula governs repeats. The birthday square-root scale explains why looking for any repeated output requires far fewer labels than trying to match one predetermined output. The uniform-independent model is an assumption about those outputs; the birthday problem does not itself establish that a particular implementation meets it.
Hash bucket Created 2026-10-13 Updated 2026-10-18
The collection of records assigned to one bucket index by a hash function. In separate chaining, an array slot refers to this collection, which may be empty.
For hash buckets, number them and write for the number of records in hash bucket . Each record belongs to exactly one hash bucket, soAn empty hash bucket contributes zero to this sum but still contributes one to the denominator . The hash table load factor therefore measures records per allocated hash bucket, not records per nonempty hash bucket. A hash bucket is a destination selected by the bucket-index hash function; with separate chaining, its records need not occupy consecutive positions in computer memory.
For the twelve-record concentrated placement in load factor of a hash table, one hash bucket contains twelve records and seven hash buckets are empty. Averaging only over nonempty hash buckets gives , whereas the hash table load factor is . This difference matters when deciding how much array capacity to allocate. For , the largest hash bucket satisfies ; the lower bound follows because at least one entry cannot be below the arithmetic mean. Neither inequality says that an actual hash function achieves a balanced placement.
Hash collision Created 2026-10-13 Updated 2026-10-31
A hash collision is a function collision of a hash function : two distinct inputs have the same output, . Repeating the same input is not a hash collision. Unequal hash values prove the keys differ; equal hash values only identify candidates that might be equal. This makes a hash function useful as a compact filter before comparing the original data.
Here is a deliberately simple example using modular arithmetic. Let for nonnegative integer keys, and let a four-bucket hash table use the further bucket index . For keys , the hash values are , while all three bucket indices are . Thus and form a hash collision for ; and share a table bucket even though their full hash values differ. Always specify which function is being compared: a table collision concerns the bucket-index function, which may discard more information than the original hash function.
With separate chaining, bucket holds all three records in a linked list. A search for visits that bucket and compares the stored keys until it finds ; a search for visits the same bucket but rejects every stored key. A hash collision changes the search work, while key comparison preserves correctness. Storing only one record per hash value would incorrectly merge distinct keys. This is the purpose of collision handling in a hash table.[ref]
The pigeonhole principle explains inevitability: if a hash function has only possible outputs, any distinct inputs contain a hash collision. In particular, a function whose domain of a function is larger than its finite codomain cannot be an injective function. This is an existence statement; it gives neither an efficient way to find the pair nor a probability for a smaller collection of keys. A particular small collection might have no hash collision at all.
For a cryptographic hash function, collision resistance asks that finding any two distinct messages with equal full digests be computationally infeasible under the specified model and resources. It does not mean that hash collisions do not exist. Preimage resistance asks a different question: given a target digest , how hard is it to find a message with ? The collision finder may choose both messages and their common digest; the preimage finder is given the digest in advance. These definitions distinguish two search tasks, independently of how a hash table stores records.[ref]
https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-107r1.pdf. Quynh Dang, NIST SP 800-107 Revision 1 (2012), section 3.1 and section 4.1, definitions of collision and preimage resistance
Hash function 2026-10-13
A hash function is a function assigning each key in an input set a value in an output set . Usually is much smaller: a long name or large integer becomes a small bucket index. Equal keys must receive equal values from the same hash function; different keys may also receive equal values. Such a hash collision means "look in the same place", and does not establish key equality. If , the pigeonhole principle makes some collisions unavoidable.
For example, modular arithmetic gives the hash function , with seven bucket indices . Store the seven keys : their values are respectively . In particular, although . A hash table is a data structure that uses these indices to locate records. With separate chaining, each bucket holds a linked list of records, so bucket retains all four keys . Inserting must not overwrite merely because their hash function values agree.
Searching for computes bucket , then compares the actual keys until it reaches . Searching for absent key reaches that same bucket and must reject every stored key. This data structure trades a search through all records for a search through one short chain, provided the hash function distributes keys adequately. A fixed hash function can perform poorly on patterned keys: already demonstrate the problem. A universal hash family introduces controlled randomness to limit the expected value of this extra work. Neither indexing nor a small collision probability inherently supplies encryption or message authentication; a cryptographic hash function has additional requirements such as collision resistance.
Hash table Created 2026-10-13 Updated 2026-10-18
A hash table stores records by key: for example, a product number can select its current stock count without scanning every product. A hash function selects a hash bucket in an array, and a collision-handling method such as separate chaining retains distinct keys assigned to the same hash bucket. The useful idea is to narrow the search to one small collection, while key equality decides which record actually matches.
Use a map interface with one value per key:
get(k) returns the associated value or an explicit absent result; put(k,v) replaces the value if an equal key is present, otherwise inserts a new record; delete(k) removes the matching record if present. The absent result must be distinguishable from every permitted stored value. Replacing a value does not increase the record count . A hash collision between unequal keys must never cause one record to replace the other.[ref]Lecture 8: Hashing I. 6.006 Introduction to Algorithms, Fall 2011 by Massachusetts Institute of Technology, 6.006 course staff; p. 1, dictionary operations and replacement of an existing key
Let denote the chosen key equality, an equivalence relation, and let be the bucket-index hash function for hash buckets. Correctness requiresThe converse is false: equal bucket indices merely identify candidates for a key equality comparison. If an implementation first computes a full hash value and then reduces it to a bucket index, equal keys must have equal values too. Keep both key equality and the hash function stable while a key is stored; changing the key so it selects another hash bucket can make its record unreachable. This distinction is explicit in the published
hashCode/equals contract.[ref]For a constructed integer example, use modular arithmetic to define and store keys with values . At , three records share hash bucket and one occupies hash bucket . The hash table load factor isIt is the mean number of records per hash bucket, including empty hash buckets, not a bound on the longest chain. With separate chaining, may exceed because records live in the chains rather than one record being confined to each array slot.
Growing this example to changes the bucket-index hash function: key now belongs to hash bucket , while keys still share hash bucket . Every record must be assigned using the new bucket-index hash function; copying the old array of chain heads unchanged is insufficient. The hash table load factor becomes .
Hash table resizing recomputes indices but does not guarantee fewer hash collisions
. Original deterministic model using , not a measured implementation. The upper panels retain keys in four and eight hash buckets; chain order is illustrative. The lower counterexample retains all four keys in hash bucket even after doubling. Details.For an insertion-only sequence starting empty with constant initial capacity, one policy doubles before inserting a new key that would make . A rebuild for separate chaining allocates the new array and transfers each existing record directly into its new chain. Since keys are already distinct, transfer needs no duplicate search. With constant-cost hashing and linking, this takes time complexity, hence at a growth threshold. Amortized analysis charges the occasional rebuild across many insertions: the old capacities form a geometric series with sum , so total rebuilding work over insertions is . This gives amortized resizing overhead; an insertion that triggers a rebuild can still take .[ref]
Lecture 9: Hashing II. 6.006 Introduction to Algorithms, Fall 2011 by Massachusetts Institute of Technology, 6.006 course staff; p. 2, rebuilding cost and geometric table doubling
The search to check for an existing key is additional work. Bounded hash table load factor together with the probabilistic assumptions in separate chaining gives expected amortized insertion, not worst-case . Rehashing alone gives no distribution guarantee: the diagram's keys all collide modulo both and . Even a low hash table load factor permits a long chain. If supporting shrinkage too, leave a gap between growth and shrink thresholds to avoid repeated rebuilding when insertions and deletions alternate near one threshold.[ref]
Lecture 9: Hashing II. 6.006 Introduction to Algorithms, Fall 2011 by Massachusetts Institute of Technology, 6.006 course staff; p. 3, expected bounds and shrinking at one-quarter occupancy
Hash table key 2026-10-18
The identifier used to select a hash table record. Key equality determines whether two identifiers name the same entry, while a hash function chooses where its lookup begins.
Hash table resizing Created 2026-10-13 Updated 2026-10-18
Changing the number of hash buckets and reassigning stored records using the new bucket-index hash function. Amortized analysis of rebuilding and expected value bounds for subsequent lookup address different costs.
Rebuild the balanced example from load factor of a hash table with while keeping exactly the same twelve records. Under , keys retain their indices, whereas keys move from hash buckets to hash buckets . The new chain lengths are twelve ones followed by four zeros; . Copying the old eight chain heads and adding eight empty heads would leave those four moved keys unreachable by the new lookup rule.
Hash table resizing from eight to sixteen hash buckets redistributes existing records
. Original modular arithmetic example for keys . Blue keys keep their indices; orange keys move because differs from . The record count stays twelve, and empty hash buckets still count towards capacity. Details.For a short algorithm correctness outline, allocate the new array, visit every old record once, compute its new bucket index, and link it into that hash bucket. At every step, each transferred record is stored exactly once at the index prescribed by the new hash function. Finishing the visit therefore preserves every key-value association and makes the new lookup rule valid. Direct transfer can skip duplicate searches because the old one-value-per-key map already established distinct equivalence classes; rebuilding is not twelve new user insertions.
Under constant-cost hashing, linking and slot initialization, separate chaining rebuilding takes time complexity: initialize new heads, examine old heads, and transfer records. For doubling, , this is in Big O notation. It is when the resize policy makes proportional to , but an enormous mostly empty old array can make scanning its heads dominate. Growing capacity can lower without shortening a particular chain: the concentrated keys all remain in hash bucket after growth from eight to sixteen.
For an insertion-only sequence starting empty, choose initial capacity and double before a genuinely new key would make . The first three growths occur before inserting records and transfer existing records. If distinct records are inserted, the transfer count is . More generally, the transferred old capacities form a geometric series; if the last is , their sum is . Initializing and scanning these geometrically growing arrays also costs in total, giving amortized rebuilding overhead per insertion. A triggering insertion still pays for its whole rebuild.[ref]
Lecture 9: Hashing II. 6.006 Introduction to Algorithms, Fall 2011 by Massachusetts Institute of Technology, 6.006 course staff; p. 2, Rehashing, How fast to grow?, and Amortized Analysis
The illustrative twelve-record resize above is an explicitly requested rebuild, not a growth triggered by this threshold policy. Checking for an equal key before growing also prevents a value replacement from triggering unnecessary growth. To combine resizing overhead with expected constant insertion time complexity, separately impose the collision and constant-cost assumptions in load factor of a hash table. Amortized analysis distributes rebuilding costs over operations; it does not randomize a poor hash function or bound a single operation's latency. With deletions, separate the grow and shrink thresholds; for example, growing when full and halving at one-quarter live occupancy leaves room for many operations between opposite rebuilds.[ref]
Lecture 9: Hashing II. 6.006 Introduction to Algorithms, Fall 2011 by Massachusetts Institute of Technology, 6.006 course staff; p. 3, Back to Hashing and Delete: halving when n reaches m/4
// Target: computer-science.bigb
Key equality Created 2026-10-13 Updated 2026-10-18
The equivalence relation used to decide whether two keys name the same record. A hash function must respect key equality; a hash collision does not establish key equality.
The choice of key equality is part of the map's meaning. In the one-value-per-key policy of hash table, one record represents each stored equivalence class of keys:
put(k,v) updates an existing equal key and adds a record only if no equal key is present. A collection that deliberately retains repeated equal keys has a different policy; its load count must count those extra records too. Repeated calls and distinct stored records are different quantities.[ref]Lecture 8: Hashing I. 6.006 Introduction to Algorithms, Fall 2011 by Massachusetts Institute of Technology, 6.006 course staff; p. 1, Dictionary Problem: distinct keys or replacement on repeated insertion
For an original example, restrict keys to two-letter strings using letters
A through Z or a through z. Declare two keys equal when replacing every uppercase letter by its lowercase counterpart gives the same string. Assign each letter its position in the alphabet, ignoring case, and define the bucket-index hash function as the sum of the two positions modulo , using modular arithmetic. Then AB and ab are equal keys and both select hash bucket . Key ba also selects hash bucket because , but is unequal to ab: order still matters. Starting empty, put(AB,7), put(ab,9), put(ba,4) leave two records, with values for the ab equivalence class and for ba; the hash table load factor is , not .The compatibility rule is one-way: . Otherwise a lookup using an equal spelling could search a different hash bucket and incorrectly report absence. Equal indices merely allow a key equality check. Both the equivalence relation and the hash function must stay consistent while records are stored; changing equality-relevant key contents can invalidate the lookup rule. The Java contract imposes these consistency and equality requirements on
equals and hashCode.[ref]Object (Java SE 25 & JDK 25). Java Platform, Standard Edition 25 API Specification by Oracle; Method Details, equals equivalence-relation contract and hashCode general contract
Linear probing 2026-10-18
An open addressing probe rule that visits modulo , using modular arithmetic, until a matching record or an appropriate stopping slot is found.[ref]
Lecture 10: Hashing III: Open Addressing. 6.006 Introduction to Algorithms, Fall 2011 by Massachusetts Institute of Technology, 6.006 course staff; Lecture 10: Hashing III: Open Addressing, p. 3, Linear Probing formula
For capacity , the hash table probe numbered , starting at zero, inspects the array indexThe hash function gives the first array index. Each subsequent hash table probe moves one slot forward, wrapping from to by modular arithmetic. Keep the hash function and key equality fixed while hash table records are stored.
Use three distinguishable slot states: occupied by a live hash table record; never used since initialization or rebuilding, written
E; or deleted, written D, a tombstone in open addressing. Lookup compares occupied hash table keys using key equality, stops at E, and continues past D.[ref]5.2 LinearHashTable: Linear Probing. Open Data Structures: An Introduction by Pat Morin; Section 5.2, three entry types and find: nil stops lookup, del does not
For an original example, take an eight-slot array, integer hash table keys, and the hash function . Start with all slots
E and insert the hash table records in that order. The insertion hash table probe traces, expressed as array indices, areThe resulting array holds hash table keys at array indices , with E in the other four slots. The first three hash table keys have the same initial array index, a hash collision; the fourth begins at but joins the same linear probing cluster. Lookup of examines array indices , rejecting before returning . Lookup of absent examines , including the stopping E: five hash table probes for a hash table load factor .Bound lookup to at most hash table probes, even if no
E remains. For algorithm termination, the first array indices are distinct: equality of and implies that divides by modular arithmetic, and forces . They therefore cover the entire finite set of slots exactly once. If no occupied hash table key matches and no E is encountered, exhausting these hash table probes establishes absence; wrapping around again supplies no new information.[ref]Lecture 10: Hashing III: Open Addressing. 6.006 Introduction to Algorithms, Fall 2011 by Massachusetts Institute of Technology, 6.006 course staff; Lecture 10: Hashing III: Open Addressing, pp. 1–2, probe permutation requirement and Search loop with m trials
The attraction is a compact array and a simple hash table probe rule. Consecutive slots can benefit from spatial locality, although actual memory cache behavior depends on representation and hardware. Correctness rests on preserving the search route; speed depends on how long that route becomes. The linear probing cluster below explains why even a moderate hash table load factor gives no universal constant lookup bound.
Linear probing cluster 2026-10-18
A maximal consecutive run of occupied or deleted slots in linear probing, bounded by never-used slots when any exist; adjacency wraps around by modular arithmetic. Deleted slots still belong to the search run.[ref]
5.2 LinearHashTable: Linear Probing. Open Data Structures: An Introduction by Pat Morin; Section 5.2.1, definition of a run using non-nil entries and modular indices
In the eight-slot example, array indices form one linear probing cluster. Inserting absent hash table key starts at , passes the occupied slots , and fills . This extends the same linear probing cluster despite having a different initial array index from . A hash collision at the initial slot is enough to make later slots compete too.
For a worst-case family, insert integer hash table keys into an empty capacity- array, using the hash function , where . They occupy array indices . Lookup of absent needs hash table probes. Taking gives hash table load factor at most while the number of hash table probes grows with . Thus occupancy alone cannot promise constant lookup work.
Before any rebuilding, bounded lookup, deletion by hash table key, and insertion with a duplicate check each have worst-case time complexity in Big O notation, assuming constant-cost hash function evaluation, array access and key equality. The counterexample gives a matching linear worst-case growth in the number of hash table probes. Hash table resizing is additional work; expensive string comparisons or hashing also fall outside these constant-cost assumptions.
Load factor of a hash table Created 2026-10-13 Updated 2026-10-18
The number of stored records divided by the number of hash buckets. For separate chaining, this is the mean chain length over all hash buckets, including empty ones.
Consider two original separate chaining placements using the deterministic hash function on nonnegative integer keys. With , keys give the balanced chain lengths . Instead, keys all select hash bucket , giving . Both store records, so both have . The maximum chain lengths are and . These are constructed placements, not measured workloads.
The same hash table load factor permits balanced and concentrated hash bucket occupancies
. Both original examples use eight hash buckets and twelve distinct integer keys. Every outlined column counts towards , including empty ones; each colored square represents one record. The dashed line marks the arithmetic mean , not the maximum chain length. Details.For an absent query, separate chaining inspects every record in the selected hash bucket. Key selects hash bucket in both examples but is stored in neither, so it takes two key equality comparisons in the balanced placement and twelve in the concentrated placement. Key selects hash bucket and instead takes one comparison in the balanced placement and zero in the concentrated placement. If an absent query's bucket index has the uniform distribution on a finite set of eight indices, its mean comparison count is in either fixed placement. That average does not limit the cost of a particular query.
For successful lookups, suppose each of the twelve stored keys is queried with equal probability, with fixed chain order and no rearrangement on access. A chain of length contributes comparison counts , irrespective of its order. ThusThe balanced placement gives comparisons; the concentrated placement gives . Even this average depends on more than : concentration appears through the squared chain lengths. These exact counts exclude computing the hash function, locating the hash bucket, and allocating records. Elapsed lookup time also depends on the cost of key equality, key length, and memory access latency; alone specifies none of them.
The expected time complexity bound for separate chaining needs a probabilistic assumption. Fix distinct stored keys and a query independently of the random choice of hash function, and require for every unequal pair, where is a constant independent of . With constant-cost hashing, array access and key equality, this suffices. The authored chaining analysis cited here uses this pairwise-collision argument; its multiplicative construction has , rather than the of simple uniform hashing.[ref]
5.1 ChainedHashTable: Hashing with Chaining. Open Data Structures: An Introduction by Pat Morin; section 5.1.1, Lemma 5.1 and the indicator-variable proof of Lemma 5.2
For the proof outline, let be the indicator random variable that stored key shares an absent query 's hash bucket. By linearity of expectation,A present query's full chain contains itself plus at most other records, giving . Stopping at the match can only improve this bound. Full independence is unnecessary for this calculation, but fixed known hash functions and keys chosen adaptively to collide are outside the stated assumption. Keeping bounded then controls expected lookup work, while the concentrated example still explains why it gives no worst-case guarantee.
For the balanced twelve-record map,
put(3,new_value) replaces a value, so and remain unchanged. An absent key such as instead adds a thirteenth record, giving if capacity stays fixed. Under a policy that stores every repeated-key record separately, another record with key would also increase ; all equal-key records necessarily share a hash bucket when the hash function respects key equality. State the map policy before interpreting the count.The appeal of the hash table load factor is that one number helps tune a space-versus-search tradeoff: more hash buckets require more array storage and can reduce expected search work under the stated assumptions. The actual chain lengths and query choices still matter.
In open addressing, counts record slots and counts live records, so . A policy retaining at least one genuinely empty slot requires ; being below one is not itself a speed guarantee. For deletion using a tombstone in open addressing, also track , the number of marked slots: counts slots that cannot terminate an unsuccessful probe. For example, gives live occupancy but nonempty-or-marked occupancy . These ratios answer different questions.[ref]
5.2 LinearHashTable: Linear Probing. Open Data Structures: An Introduction by Pat Morin; section 5.2, three entry types, counters n and q, and find stopping at nil
Memoization key 2026-10-14
A memoization key identifies all information that determines a reusable answer. Write for explicit arguments and for relevant context. For a function and key function , the necessary value condition isThis implication need hold only for contexts in which the entry can be reused. The condition concerns key equality, not merely equality of hash function outputs: a hash table must resolve hash collisions by comparing complete keys. Include the identity or version of the procedure if one table stores results for several procedures or changing implementations.
For an original toy example, let . Caching only by after incorrectly returns for , whose answer is . The pair is complete for this function. If is hidden in mutable configuration, either freeze that configuration for the memoization cache lifetime, include a reliable version in the key, or invalidate affected entries before reuse. A version is sufficient only if every relevant change updates it. Object identity alone is likewise insufficient for a mutable list whose contents determine the answer.
Open addressing 2026-10-18
A hash table collision-handling method storing at most one live record per array slot. A hash function chooses a starting slot, and a probe rule chooses further slots. Unlike separate chaining, records occupy the slots themselves.
Pairing function Created 2026-10-03 Updated 2026-10-14
A pairing function is a computable function that gives a bijection from the Cartesian product to , with two computable functions recovering its coordinates. Here consists of the natural numbers, including zero. If is the pairing function and its decoding functions, the requirements areEvery ordered pair has exactly one code, every code represents an ordered pair, and decoding always terminates. For a bijection given by a total computable function, computability of the inverse function also follows by enumerating all ordered pairs until the one with code appears. A primitive recursive pairing function makes the stronger requirement that both encoding and coordinate decoding are primitive recursive.
The Cantor pairing function makes this concrete through triangular numbers:On the diagonal , list . There are ordered pairs there, and ordered pairs on earlier diagonals. Their codes therefore occupy precisely the consecutive natural numbers from through . These intervals touch without overlapping and cover all natural numbers; within each interval the offset determines the ordered pair. This proves both injectivity and surjectivity, hence the bijection. It also explains why the infinite grid is a countably infinite set: every ordered pair is reached after finitely many steps. A row-by-row listing would never finish its first infinite row. Authored treatments give the same diagonal construction with the coordinates exchanged.[ref]
https://www.cs.cmu.edu/~cdm/resources/02-coding.pdf. Klaus Sutner, Primitive Recursion, Carnegie Mellon University, spring 2021, slides 9–13: pairing systems and the Cantor polynomial
For example, the Cantor pairing function givesThe order of the coordinates matters: and are different ordered pairs with different codes.
The Cantor pairing function on a finite window: labels are codes, and the first 21 ordered pairs fill diagonals zero through five
. Details. To decode a natural number , find the unique diagonal index satisfyingThe inequality gives , so both recovered coordinates are natural numbers. At , , hence , , and . At , and both coordinates are zero. Solving the quadratic inequality gives the equivalent floor function expressionThis is exact as a statement about the real numbers and their square roots. An implementation using floating-point arithmetic can round across a diagonal boundary, especially for large . Use an exact integer square root instead: with computed using integer arithmetic, . Alternatively, search for the diagonal using exact integer comparisons. The primitive recursive pairing function proof below uses bounded minimization and needs no approximate square root.
A pairing function is a reversible encoding: unlike a hash function mapping arbitrarily many inputs into a fixed finite range, it loses no coordinates. This works because the mathematical natural numbers have no upper bound. A machine word with binary digits has possible values, while two such words have possible ordered pairs; a bijection into one word of the same width is impossible. Evaluating the Cantor pairing function in a fixed-width integer type can overflow, including in the intermediate product . Exact implementation requires sufficiently large integer storage or an explicit restricted input range. One mathematical code need not occupy fewer binary digits than its two inputs.
Iterating a pairing function gives a reversible encoding of tuples of any fixed positive length. With the left-nesting convention, the Cantor pairing function encodes asDecode the outer ordered pair first: gives . Decode its first coordinate to recover , giving the nested ordered pair and thus the original tuple .
The tuple length and nesting convention must be known. The same code represents as a two-entry tuple and as a three-entry tuple; nesting alone does not make variable-length tuples self-describing. To encode variable-length tuples, supply their length or another explicit termination convention as part of the encoding. This simple change of representation is useful in computability theory and Gödel numbering: a function of several natural numbers can be studied through a single numerical input, while all coordinates remain recoverable. The striking fact is that a whole infinite grid can be serialized without omitting a point.
A historical reference for comparing sets through bijections is Georg Cantor's paper Ein Beitrag zur Mannigfaltigkeitslehre, published in 1878 in volume 84 of Journal für die reine und angewandte Mathematik, pages 242–258.[ref]
https://doi.org/10.1515/crelle-1878-18788413. Georg Cantor, Ein Beitrag zur Mannigfaltigkeitslehre, 1878: publisher bibliographic record
Assume the supplied hash function is stable and produces valid table indices. The representation invariant places each name in its hashed bucket, permits at most one entry per name, and requires finite acyclic, disjoint bucket chains.
def store(name: String, number: String): Unit = {
val bucket = hash(name)
val entry = find(name, table(bucket))
if (entry == null) {
table(bucket) = new Entry(name, number, table(bucket))
} else {
entry.number = number
}
}If the key exists, updating its associated number implements map override without creating a duplicate entry. Otherwise a new entry is prepended to the correct bucket and leaves every existing mapping unchanged. Its immutable name preserves bucket membership. Thus the mapping afterwards is the old mapping overridden at precisely the supplied key. Hash collisions between different names do not imply key equality and are handled by separate chaining.
The relevant quantity is the hash-table load factor , where is the number of distinct keys and the bucket count. With a suitable distribution of hashes, separate chaining has expected operation cost , treating key operations as constant-cost. Keeping only one hundred buckets while grows therefore increases average search length.
Balanced binary search trees could reduce a bucket search from linear time in its occupancy to logarithmic time. Unbalanced binary search trees provide no such guarantee: insertion order can produce a chain. Even balanced trees add comparison and node-management overhead, which may dominate for small buckets.
A usual first remedy is grow the table and rehash its entries, keeping the load factor bounded. Geometric growth gives amortized constant resizing overhead per insertion; with suitable hashing, expected lookup, update and insertion costs remain constant. Resizing is when performed and is not a worst-case constant-time guarantee for that particular operation. Balanced buckets can still be useful for heavy or adversarial collisions, but replacing every bucket tree does not by itself repair a poor hash function. For variable-length strings, hashing and string comparisons add their own character-processing costs.
With a directly indexed array, use two parallel count arrays, or one array of count records, at each user identity. Both queries and increments take running time, with no hash collision. However, reserving positions for each of two four-byte counters uses about million bytes, roughly MiB before object overhead, even when only a few users have payments. Index zero is unused and all valid positions initially contain zero.
With a linked list, store one node
(user, countIn, countOut, next) for each active user. A scan locates a record, returning zero counts if absent; an increment creates a missing record or updates its counter. Storage is for stored users, but a query or update can require running time. Nodes also carry pointer and allocation overhead and lack direct indexed access.With a hash table using separate chaining, compute a hash bucket from the user identity and store its record in that bucket's linked list. The same zero-default convention applies to a missing record. With buckets and a well-distributing hash function, the expected operation cost is in terms of the load factor of a hash table; worst-case cost remains under severe collisions. Storage is , but a permanently fixed cannot maintain constant expected cost as grows without bound. A good distribution and, where permitted, hash table resizing address that trade-off.
The following method belongs inside the source class and uses the helper from part (d). It preserves the existing outgoing count, and a newly encountered user starts with exactly one incoming and zero outgoing payments.
def recordIncoming(user: Int): Unit = {
require(1 <= user && user <= 99999999, "invalid user identity")
val bucket = hash(user)
val p = find(user, table(bucket))
if (p == null) {
table(bucket) = new PaymentsHash.Node(user, 1, 0, table(bucket))
} else {
require(p.countIn < Int.MaxValue, "incoming count is full")
p.countIn += 1
}
}On a hit, exactly one field is incremented after the overflow check. On a miss, inserting at the bucket head preserves all existing records and gives precisely the required change from implicit zero to one. The given hash function must return an index in consistently for a given user. Its actual formula is not needed by this method. The nested private node class is accessible to its companion class in Scala, so retaining the source's
PaymentsHash.Node visibility is valid.[ref]Scala 2.13 classes and objects specification. Modifiers: private members are accessible to the enclosing template and its companion
Separate chaining Created 2026-10-13 Updated 2026-10-20
With separate chaining, each hash bucket in a hash table contains a collection of records, often a linked list. Lookup computes the bucket index, then follows that chain until a key equality comparison succeeds or the chain ends. A hash collision therefore affects the search work without merging unequal keys. Deletion searches the same chain and unlinks the matching record; in a singly linked list, remembering the preceding record during the search permits the unlink.[ref]
For the four-key integer example in hash table, insert a new record at the head of its chain after checking that its key is absent. Inserting in that order makes hash bucket hold , hash bucket hold , and the other two hash buckets empty. All five subsequent operations below select hash bucket because :
Separate chaining traces lookup, replacement, deletion and insertion through key equality
. Original deterministic model with . The table counts actual keys inspected, not elapsed machine time. Operations occur from top to bottom; only an absent key adds a new record, and the untouched record remains in hash bucket . Details.get(5) rejects key , accepts key , and returns after two key equality comparisons. get(13) rejects and reports absence after three comparisons. put(5,B*) examines and replaces the value without changing . delete(9) examines just the head record, removes it, and gives . Finally, put(13,E) rejects before inserting the new head record; returns to and the chain is . The successive hash table load factors are . These counts follow from the stipulated chain order; a different insertion policy changes the successful-search counts.For a chain of length , lookup and deletion by key take time complexity in Big O notation. The same applies to
put before any resizing, since replacement semantics require checking for an existing equal key. Head insertion alone is if absence is already known; that is a different precondition. These bounds assume bucket-index hashing, array access, key equality comparisons, allocation and link updates. A long string or large integer can make hashing or comparison depend on its encoded length, so counting record visits alone does not establish constant running time.Under simple uniform hashing, each distinct key's bucket index is an independent random variable with a uniform distribution on a finite set of indices. The keys and query are fixed independently of this random assignment. Then lookup has expected time complexity, where is the hash table load factor; it is expected when stays bounded. These are model assumptions, not an automatic consequence of using a deterministic hash function.[ref]
Lecture 8: Hashing I. 6.006 Introduction to Algorithms, Fall 2011 by Massachusetts Institute of Technology, 6.006 course staff; pp. 4–5, chaining worst case and simple uniform hashing assumption
Here is the short calculation. For an absent query and stored keys , let be the indicator random variable of . The number of records inspected has expected valueby linearity of expectation. For a present fixed query, scanning its entire chain inspects at most itself plus all other colliding records, with expected value ; stopping at the match only decreases this upper bound. Adding constant hashing and bucket access yields expected for either query. The argument needs pairwise collision bounds; it does not require all the indicator random variables to be independent. A universal hash family can provide a related bound by random choice of a hash function for a fixed key set, as explained in that article.
The worst case remains , and an absent query takes comparisons if all records occupy its hash bucket. For instance, all collide under . Separate chaining remains correct, but a sequence of insertions that each checks the existing chain can take quadratic total work. Amortized analysis of resizing does not remove this search cost, and an adaptive choice of keys based on a known hash function is outside the stated simple uniform hashing model.










