Fundamental Data Structures PDF
Fundamental Data Structures PDF
Contents
1
Introduction
1.1
1.1.1
1.1.2
1.1.3
Typical operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.4
Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.5
Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.6
See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.7
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.8
Further . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.9
External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Data structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.1
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.2
Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.3
Language support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.4
See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.5
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.6
Further reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.7
External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Analysis of algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.1
Cost models
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.2
Run-time analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.3
Relevance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
1.3.4
Constant factors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
1.3.5
See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
1.3.6
Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
1.3.7
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
1.2
1.3
Sequences
13
2.1
13
2.1.1
History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
2.1.2
Abstract arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
2.1.3
Implementations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
ii
CONTENTS
2.2
2.3
2.1.4
Language support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
2.1.5
See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
2.1.6
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
2.1.7
External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
16
2.2.1
History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
2.2.2
Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
2.2.3
17
2.2.4
Eciency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
2.2.5
Dimension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
2.2.6
See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
2.2.7
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
2.2.8
External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
Dynamic array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
2.3.1
21
2.3.2
21
2.3.3
Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21
2.3.4
Variants
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
2.3.5
Language support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
2.3.6
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
2.3.7
External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
Dictionaries
24
3.1
Associative array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
3.1.1
Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
3.1.2
Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
3.1.3
Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
3.1.4
Language support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
3.1.5
See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
3.1.6
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
3.1.7
External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
Association list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
3.2.1
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
Hash table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
3.3.1
Hashing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
3.3.2
Key statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
3.3.3
Collision resolution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
3.3.4
Dynamic resizing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
3.3.5
Performance analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
3.3.6
Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
3.3.7
Uses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33
3.3.8
Implementations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33
3.2
3.3
CONTENTS
3.3.9
3.4
iii
History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
34
3.3.11 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
35
35
Linear probing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
3.4.1
Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
3.4.2
Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
3.4.3
36
3.4.4
See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
3.4.5
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
3.4.6
External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
37
4.1
Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37
4.2
Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
39
4.3
Content license . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
40
Chapter 1
Introduction
1.1 Abstract data type
programs.
The term abstract data type can also be regarded as
a generalised approach of a number of algebraic structures, such as lattices, groups, and rings.[2] The notion of
abstract data types is related to the concept of data abstraction, important in object-oriented programming and
design by contract methodologies for software development .
CHAPTER 1. INTRODUCTION
and
fetch(V), that yields a value;
fetch(V) always returns the value x used in the most Preconditions, postconditions, and invariants In
recent store(V,x) operation on the same variable V. imperative-style denitions, the axioms are often expressed by preconditions, that specify when an operation
As in so many programming languages, the operation may be executed; postconditions, that relate the states of
store(V,x) is often written V x (or some similar nota- the ADT before and after the execution of each operation), and fetch(V) is implied whenever a variable V is tion; and invariants, that specify properties of the ADT
used in a context where a value is required. Thus, for that are not changed by the operations.
example, V V + 1 is commonly understood to be a
shorthand for store(V,fetch(V) + 1).
Example: abstract stack (imperative) As another
In this denition, it is implicitly assumed that storing a example, an imperative denition of an abstract stack
value into a variable U has no eect on the state of a dis- could specify that the state of a stack S can be modied
tinct variable V. To make this assumption explicit, one only by the operations
could add the constraint that
if U and V are distinct variables, the sequence {
store(U,x); store(V,y) } is equivalent to { store(V,y);
store(U,x) }.
A stack ADT denition usually includes also a Booleanvalued function empty(S) and a create() operation that returns a stack instance, with axioms equivalent to
create() S for any stack S (a newly created stack is In a functional-style denition there is no need for a credistinct from all previous stacks)
ate operation. Indeed, there is no notion of stack instance. The stack states can be thought of as being po empty(create()) (a newly created stack is empty)
tential states of a single stack structure, and two stack
states that contain the same values in the same order are
not empty(push(S,x)) (pushing something into a
considered to be identical states. This view actually mirstack makes it non-empty)
rors the behavior of some concrete implementations, such
as linked lists with hash cons.
Single-instance style Sometimes an ADT is dened
as if only one instance of it existed during the execution
of the algorithm, and all operations were applied to that
instance, which is not explicitly notated. For example,
the abstract stack above could have been dened with operations push(x) and pop(), that operate on the only existing stack. ADT denitions in this style can be easily
rewritten to admit multiple coexisting instances of the
ADT, by adding an explicit instance parameter (like S
in the previous example) to every operation that uses or
modies the implicit instance.
CHAPTER 1. INTRODUCTION
one module with another module with the
same functional behavior but with dierent
complexity tradeos, the user of this code
will be unpleasantly surprised. I could tell
him anything I like about data abstraction,
and he still would not want to use the code.
Complexity assertions have to be part of the
interface.
Alexander Stepanov[3]
1.1.2
Encapsulation
Abstraction provides a promise that any implementation
of the ADT has certain properties and abilities; knowing
these is all that is required to make use of an ADT object.
The user does not need any technical knowledge of how
the implementation works to use the ADT. In this way,
the implementation may be complex but will be encapsulated in a simple interface when it is actually used.
Localization of change
Deque
List
1.1.3
Typical operations
Some operations that are often specied for ADTs (possibly under other names) are
Map
Multimap
Multiset
Priority queue
Queue
Set
Stack
Tree
Graph
1.1.5
Implementation
Functional-style interface
Functional-style ADT
denitions are more appropriate for functional programming languages, and vice-versa. However, one can provide a functional style interface even in an imperative language like C. For example:
ADT libraries
Many modern programming languages, such as C++ and
Java, come with standard libraries that implement several
common ADTs, such as those listed above.
CHAPTER 1. INTRODUCTION
1.1.6
See also
Initial algebra
keys
hash
function
00
John Smith
Lisa Smith
Sandra Dee
01
521-8976
02
521-1234
03
:
13
14
521-9655
15
buckets
A hash table
Formal methods
Functional specication
Liskov substitution principle
Object-oriented programming
Type system
Type theory
Algebraic data type
Generalized algebraic data type
1.1.7
References
1.2.1 Overview
Modern languages also generally support modular programming, the separation between the interface of a library module and its implementation. Some provide
opaque data types that allow clients to hide implementation details. Object-oriented programming languages,
An associative array (also called a dictionary or such as C++, Java and Smalltalk may use classes for this
map) is a more exible variation on an array, in purpose.
which name-value pairs can be added and deleted Many known data structures have concurrent versions that
freely. A hash table is a common implementation of allow multiple computing threads to access the data strucan associative array.
ture simultaneously.
A union type species which of a number of permitted primitive types may be stored in its instances,
1.2.4 See also
e.g. oat or long integer. Contrast with a record,
which could be dened to contain a oat and an in Abstract data type
teger; whereas in a union, there is only one value
at a time. Enough space is allocated to contain the
Concurrent data structure
widest member datatype.
Data model
A tagged union (also called a variant, variant record,
Dynamization
discriminated union, or disjoint union) contains an
additional eld indicating its current type, for en Linked data structure
hanced type safety.
List of data structures
A set is an abstract data structure that can store specic values, in no particular order and with no du Persistent data structure
plicate values.
Plain old data structure
Graphs and trees are linked abstract data structures
composed of nodes. Each node contains a value and
one or more pointers to other nodes arranged in a hi- 1.2.5 References
erarchy. Graphs can be used to represent networks,
while variants of trees can be used for sorting and [1] Paul E. Black (ed.), entry for data structure in Dictionary
of Algorithms and Data Structures. U.S. National Institute
searching, having their nodes arranged in some relof Standards and Technology. 15 December 2004. Online
ative order based on their values.
An object contains data elds, like a record, as well
as various methods which operate on the contents
of the record. In the context of object-oriented
programming, records are known as plain old data
structures to distinguish them from objects.
CHAPTER 1. INTRODUCTION
1.2.7
External links
The latter is more cumbersome to use, so its only employed when necessary, for example in the analysis of
arbitrary-precision arithmetic algorithms, like those used
in cryptography.
In theoretical analysis of algorithms it is common to estimate their complexity in the asymptotic sense, i.e., to
estimate the complexity function for arbitrarily large input. Big O notation, Big-omega notation and Big-theta
notation are used to this end. For instance, binary search
is said to run in a number of steps proportional to the
1.3.2
Run-time analysis
Run-time analysis is a theoretical classication that estimates and anticipates the increase in running time (or
run-time) of an algorithm as its input size (usually denoted
as n) increases. Run-time eciency is a topic of great
interest in computer science: A program can take seconds, hours or even years to nish executing, depending
on which algorithm it implements (see also performance
analysis, which is the analysis of an algorithms run-time
in practice).
9
time of that algorithm. In other words, for a given input
size n greater than some n0 and a constant c, the running
time of that algorithm will never be larger than c f(n).
This concept is frequently expressed using Big O notation.
For example, since the run-time of insertion sort grows
quadratically as its input size increases, insertion sort can
be said to be of order O(n).
Big O notation is a convenient way to express the worstcase scenario for a given algorithm, although it can also
be used to express the average-case for example,
the worst-case scenario for quicksort is O(n), but the
average-case run-time is O(n log n).[7]
Take as an example a program that looks up a specic entry in a sorted list of size n. Suppose this program were
implemented on Computer A, a state-of-the-art machine,
using a linear search algorithm, and on Computer B, a
much slower machine, using a binary search algorithm.
Benchmark testing on the two computers running their It is clearly seen that the rst algorithm exhibits a linear
respective programs might look something like the fol- order of growth indeed following the power rule. The emlowing:
pirical values for the second one are diminishing rapidly,
Based on these metrics, it would be easy to jump to the suggesting it follows another rule of growth and in any
conclusion that Computer A is running an algorithm that case has much lower local orders of growth (and improvis far superior in eciency to that of Computer B. How- ing further still), empirically, than the rst one.
ever, if the size of the input-list is increased to a sucient
number, that conclusion is dramatically demonstrated to
Evaluating run-time complexity
be in error:
Computer A, running the linear search program, exhibits
a linear growth rate. The programs run-time is directly
proportional to its input size. Doubling the input size doubles the run time, quadrupling the input size quadruples
the run-time, and so forth. On the other hand, Computer B, running the binary search program, exhibits a
logarithmic growth rate. Doubling the input size only increases the run time by a constant amount (in this example, 50,000 ns). Even though Computer A is ostensibly a
faster machine, Computer B will inevitably surpass Computer A in run-time because its running an algorithm with
a much slower growth rate.
Orders of growth
Main article: Big O notation
Informally, an algorithm can be said to exhibit a growth
rate on the order of a mathematical function if beyond
a certain input size n, the function f(n) times a positive
constant provides an upper bound or limit for the run-
10
CHAPTER 1. INTRODUCTION
T1 + T2 + T3 + T7 .
The loops in steps 4, 5 and 6 are trickier to evaluate. The
outer loop test in step 4 will execute ( n + 1 ) times (note
that an extra step is required to terminate the for loop,
hence n + 1 and not n executions), which will consume
T4 ( n + 1 ) time. The inner loop, on the other hand, is
governed by the value of i, which iterates from 1 to i. On
the rst pass through the outer loop, j iterates from 1 to
1: The inner loop makes one pass, so running the inner
loop body (step 6) consumes T6 time, and the inner loop
test (step 5) consumes 2T5 time. During the next pass
through the outer loop, j iterates from 1 to 2: the inner
loop makes two passes, so running the inner loop body
(step 6) consumes 2T6 time, and the inner loop test (step
5) consumes 3T5 time.
[1 2
]
that
+
2 (n + n) T6
[ 1 Prove
]
2
(n
+
3n)
T
+
(n
+
1)T
+
T
5
4
1 +
2
2
T2 +
T
+
T
cn
,
n
n
[1 2 0
]
[1 3 2 7 ]
2 (n + n) T6 + 2 (n + 3n) T5 +(n+
1)T4 + T1 + T2 + T3 + T7
(n2 +n)T6 +(n2 +3n)T5 +(n+1)T4 +
T1 + T2 + T3 + T7 (for n 0)
Let k be a constant greater than or equal to
[T1 ..T7 ]
T6 (n2 + n) + T5 (n2 + 3n) + (n + 1)T4 + T1 +
T2 + T3 + T7 k(n2 + n) + k(n2 + 3n) +
kn + 5k
= 2kn2 + 5kn + 5k 2kn2 + 5kn2 + 5kn2
(for n 1) = 12kn2 [
]
1
2
Therefore
(n
+
n)
T6
+
2
[1 2
]
2 (n + 3n) T5 + (n + 1)T4 + T1 + T2 +
T3 + T7 cn2 , n n0 for c = 12k, n0 = 1
]
1 2
(n + n)
2
n
n
4+ i=1 i 4+ i=1 n = 4+n2 5n2
(for n 1) = O(n2 ).
The total time required to run the outer loop test can be
Growth rate analysis of other resources
evaluated similarly:
2T5 + 3T5 + 4T5 + + (n 1)T5 + nT5 +
(n + 1)T5
= T5 + 2T5 + 3T5 + 4T5 + + (n 1)T5 +
nT5 + (n + 1)T5 T5
which can be factored as
1.3.3 Relevance
]
[
]
Algorithm analysis is important in practice because the
1 2
1 2
f (n) =
(n + n) T6 + (n + 3n) T5 +(n+1)T4 +T
accidental
unintentional
use of an inecient algorithm
1 +T2 +Tor
3 +T
7
2
2
can signicantly impact system performance. In timeAs a rule-of-thumb, one can assume that the highest- sensitive applications, an algorithm taking too long to
order term in any given function dominates its rate of run can render its results outdated or useless. An inefgrowth and thus denes its run-time order. In this ex- cient algorithm can also end up requiring an uneconomample, n is the highest-order term, so one can conclude ical amount of computing power or storage in order to
that f(n) = O(n). Formally this can be proven as follows: run, again rendering it practically useless.
1.3.4
Constant factors
11
Smoothed analysis
For large data linear or quadratic factors cannot be ignored, but for small data an asymptotically inecient algorithm may be more ecient. This is particularly used
in hybrid algorithms, like Timsort, which use an asymptotically ecient algorithm (here merge sort, with time
complexity n log n ), but switch to an asymptotically inecient algorithm (here insertion sort, with time complexity n2 ) for small data, as the simpler algorithm is
faster on small data.
1.3.5
See also
Amortized analysis
Asymptotic computational complexity
Best, worst and average case
Big O notation
Computational complexity theory
Master theorem
NP-Complete
Numerical analysis
Polynomial time
Program optimization
Proling (computer programming)
Scalability
of
abstraction?,
csthe-
1.3.7 References
Cormen, Thomas H.; Leiserson, Charles E.; Rivest,
Ronald L. & Stein, Cliord (2001). Introduction to
Algorithms. Chapter 1: Foundations (Second ed.).
Cambridge, MA: MIT Press and McGraw-Hill. pp.
3122. ISBN 0-262-03293-7.
Sedgewick, Robert (1998). Algorithms in C, Parts 14: Fundamentals, Data Structures, Sorting, Searching (3rd ed.). Reading, MA: Addison-Wesley Professional. ISBN 978-0-201-31452-6.
12
Knuth, Donald. The Art of Computer Programming.
Addison-Wesley.
Greene, Daniel A.; Knuth, Donald E. (1982). Mathematics for the Analysis of Algorithms (Second ed.).
Birkhuser. ISBN 3-7643-3102-X.
Goldreich, Oded (2010). Computational Complexity: A Conceptual Perspective. Cambridge University Press. ISBN 978-0-521-88473-0.
CHAPTER 1. INTRODUCTION
Chapter 2
Sequences
2.1 Array data type
13
14
CHAPTER 2. SEQUENCES
2.1.3
Implementations
2.1.4
Language support
or, in general, where the valid range of each index depends on the values of all preceding indices.
This representation for multi-dimensional arrays is quite
prevalent in C and C++ software. However, C and C++
will use a linear indexing formula for multi-dimensional
arrays that are declared as such, e.g. by int A[10][20] or
int A[m][n], instead of the traditional int **A.[6]:p.81
Indexing notation
Most programming languages that support arrays support the store and select operations, and have special syntax for indexing. Early languages used parentheses, e.g.
A(i,j), as in FORTRAN; others choose square brackets,
e.g. A[i,j] or A[i][j], as in Algol 60 and Pascal.
Multi-dimensional arrays
Index types
Bounds checking
Some languages (like Pascal and Modula) perform
bounds checking on every access, raising an exception
or aborting the program when any index is out of its
valid range. Compilers may allow these checks to be
turned o to trade safety for speed. Other languages (like
FORTRAN and C) trust the programmer and perform no
15
checks. Good compilers may also analyze the program provided via standard extension libraries for other general
to determine the range of possible values that the index purpose programming languages (such as the widely used
may have, and this analysis may lead to bounds-checking NumPy library for Python).
elimination.
String types and arrays
Index origin
Some languages, such as C, provide only zero-based array
types, for which the minimum valid value for any index
is 0. This choice is convenient for array implementation
and address computations. With a language such as C,
a pointer to the interior of any array can be dened that
will symbolically act as a pseudo-array that accommodates negative indices. This works only because C does
not check an index against bounds when used.
Other languages provide only one-based array types,
where each index starts at 1; this is the traditional convention in mathematics for matrices and mathematical
sequences. A few languages, such as Pascal, support
n-based array types, whose minimum legal indices are
chosen by the programmer. The relative merits of each
choice have been the subject of heated debate. Zerobased indexing has a natural advantage to one-based indexing in avoiding o-by-one or fencepost errors.[7]
Resizing
Some languages allow dynamic arrays (also called resizable, growable, or extensible): array variables whose index ranges may be expanded at any time after creation,
without changing the values of its current elements.
16
CHAPTER 2. SEQUENCES
For one-dimensional arrays, this facility may be provided [3] John Mitchell, Concepts of Programming Languages.
Cambridge University Press.
as an operation append(A,x)" that increases the size of
the array A by one and then sets the value of the last el[4] Lukham, Suzuki (1979), Verication of array, record,
ement to x. Other array types (such as Pascal strings)
and pointer operations in Pascal. ACM Transactions on
provide a concatenation operator, which can be used toProgramming Languages and Systems 1(2), 226244.
gether with slicing to achieve that eect and more. In
some languages, assigning a value to an element of an [5] see the denition of a matrix
array automatically extends the array, if necessary, to include that element. In other array types, a slice can be [6] Brian W. Kernighan and Dennis M. Ritchie (1988), The
C programming Language. Prentice-Hall, 205 pages.
replaced by an array of dierent size with subsequent elements being renumbered accordingly as in Pythons [7] Edsger W. Dijkstra, Why numbering should start at zero
list assignment "A[5:5] = [10,20,30]", that inserts three
new elements (10,20, and 30) before element "A[5]". Resizable arrays are conceptually similar to lists, and the two 2.1.7 External links
concepts are synonymous in some languages.
NISTs Dictionary of Algorithms and Data StrucAn extensible array can be implemented as a xed-size
tures: Array
array, with a counter that records how many elements are
actually in use. The append operation merely increments
the counter; until the whole array is used, when the append operation may be dened to fail. This is an imple- 2.2 Array data structure
mentation of a dynamic array with a xed capacity, as in
the string type of Pascal. Alternatively, the append op- Not to be confused with Array data type.
eration may re-allocate the underlying array with a larger
size, and copy the old elements to the new area.
In computer science, an array data structure or simply
an array is a data structure consisting of a collection of elements (values or variables), each identied by at least one
2.1.5 See also
array index or key. An array is stored so that the position
of each element can be computed from its index tuple by
Array access analysis
a mathematical formula.[1][2][3] The simplest type of data
Array programming
structure is a linear array, also called one-dimensional array.
Array slicing
For example, an array of 10 32-bit integer variables, with
Bounds checking and index checking
indices 0 through 9, may be stored as 10 words at memory
addresses 2000, 2004, 2008, 2036, so that the element
Bounds checking elimination
with index i has the address 2000 + 4 i.[4]
Delimiter-separated values
Because the mathematical concept of a matrix can be represented as a two-dimensional grid, two-dimensional ar Comparison of programming languages (array)
rays are also sometimes called matrices. In some cases
the term vector is used in computing to refer to an ar Parallel array
ray, although tuples rather than vectors are more correctly
the mathematical equivalent. Arrays are often used to imRelated types
plement tables, especially lookup tables; the word table is
sometimes used as a synonym of array.
Variable-length array
Arrays are among the oldest and most important data
Dynamic array
structures, and are used by almost every program. They
are also used to implement many other data structures,
Sparse array
such as lists and strings. They eectively exploit the addressing logic of computers. In most modern computers and many external storage devices, the memory is a
2.1.6 References
one-dimensional array of words, whose indices are their
[1] Robert W. Sebesta (2001) Concepts of Programming addresses. Processors, especially vector processors, are
Languages. Addison-Wesley. 4th edition (1998), 5th edi- often optimized for array operations.
tion (2001), ISBN 9780201385960
[2] K. Jensen and Niklaus Wirth, PASCAL User Manual and
Report. Springer. Paperback edition (2007) 184 pages,
ISBN 978-3540069508
17
portably.
Arrays can be used to determine partial or complete
control ow in programs, as a compact alternative to
(otherwise repetitive) multiple IF statements. They are
known in this context as control tables and are used
in conjunction with a purpose built interpreter whose
control ow is altered according to values contained in
the array. The array may contain subroutine pointers (or
relative subroutine numbers that can be acted upon by
SWITCH statements) that direct the path of the execution.
2.2.1
History
The rst digital computers used machine-language programming to set up and access array structures for data
tables, vector and matrix computations, and for many
other purposes. Von Neumann wrote the rst arraysorting program (merge sort) in 1945, during the building of the rst stored-program computer.[6]p. 159 Array indexing was originally done by self-modifying code, and
later using index registers and indirect addressing. Some
mainframes designed in the 1960s, such as the Burroughs
B5000 and its successors, used memory segmentation to
perform index-bounds checking in hardware.[7]
Assembly languages generally have no special support
for arrays, other than what the machine itself provides.
The earliest high-level programming languages, including FORTRAN (1957), COBOL (1960), and ALGOL
60 (1960), had support for multi-dimensional arrays, and
so has C (1972). In C++ (1983), class templates exist
for multi-dimensional arrays whose dimension is xed at
runtime[3][5] as well as for runtime-exible arrays.[2]
2.2.2
Applications
18
CHAPTER 2. SEQUENCES
gle subscript which can either represent a row or column changed by changing the base address B. Thus, if a twoindex.
dimensional array has rows and columns indexed from 1
As an example consider the C declaration int anArray- to 10 and 1 to 20, respectively, then replacing B by B + c1 3 c1 will cause them to be renumbered from 0 through
Name[10];
9 and 4 through 23, respectively. Taking advantage of
Syntax : datatype anArrayname[sizeofArray];
this feature, some languages (like FORTRAN 77) specify
In the given example the array can contain 10 elements of that array indices begin at 1, as in mathematical tradition;
any value available to the int type. In C, the array element while other languages (like Fortran 90, Pascal and Algol)
indices are 0-9 inclusive in this case. For example, the ex- let the user choose the minimum value for each index.
pressions anArrayName[0] and anArrayName[9] are the
rst and last elements respectively.
Dope vectors
For a vector with linear addressing, the element with index i is located at the address B + c i, where B is a xed The addressing formula is completely dened by the dibase address and c a xed constant, sometimes called the mension d, the base address B, and the increments c1 , c2 ,
, ck. It is often useful to pack these parameters into a
address increment or stride.
record called the arrays descriptor or stride vector or dope
If the valid element indices begin at 0, the constant B is
vector.[2][3] The size of each element, and the minimum
simply the address of the rst element of the array. For
and maximum values allowed for each index may also be
this reason, the C programming language species that
included in the dope vector. The dope vector is a comarray indices always begin at 0; and many programmers
plete handle for the array, and is a convenient way to pass
will call that element "zeroth" rather than rst.
arrays as arguments to procedures. Many useful array
However, one can choose the index of the rst element by slicing operations (such as selecting a sub-array, swapan appropriate choice of the base address B. For example, ping indices, or reversing the direction of the indices) can
if the array has ve elements, indexed 1 through 5, and the be performed very eciently by manipulating the dope
base address B is replaced by B + 30c, then the indices of vector.[2]
those same elements will be 31 to 35. If the numbering
does not start at 0, the constant B may not be the address
Compact layouts
of any element.
Often the coecients are chosen so that the elements occupy a contiguous area of memory. However, that is not
necessary. Even if arrays are always created with conFor a two-dimensional array, the element with indices i,j tiguous elements, some array slicing operations may crewould have address B + c i + d j, where the coe- ate non-contiguous sub-arrays from them.
cients c and d are the row and column address increments,
There are two systematic compact layouts for a tworespectively.
dimensional array. For example, consider the matrix
More generally, in a k-dimensional array, the address of
an element with indices i1 , i2 , , ik is
1 2 3
A = 4 5 6.
B + c1 i1 + c2 i2 + + ck ik.
7 8 9
Multidimensional arrays
the address of the element whose indices are all zero. As In systems which use processor cache or virtual memory,
in the one-dimensional case, the element indices may be scanning an array is much faster if successive elements
19
through individual element access. The speedup of such
optimized routines varies by array element size, architecture, and implementation.
20
CHAPTER 2. SEQUENCES
1
4
7
2
5
8
[2] Bjoern Andres; Ullrich Koethe; Thorben Kroeger; Hamprecht (2010). Runtime-Flexible Multi-dimensional Arrays and Views for C++98 and C++0x. arXiv:1008.2909
[cs.DS].
[3] Garcia, Ronald; Lumsdaine, Andrew (2005). MultiArray: a C++ library for generic programming with arrays. Software: Practice and Experience 35 (2): 159
188. doi:10.1002/spe.630. ISSN 0038-0644.
[4] David R. Richardson (2002), The Book on Data Structures. iUniverse, 112 pages. ISBN 0-595-24039-9, ISBN
978-0-595-24039-5.
2.2.5
Dimension
2.2.6
See also
Dynamic array
Parallel array
Variable-length array
Bit array
[7] Levy, Henry M. (1984), Capability-based Computer Systems, Digital Press, p. 22, ISBN 9780932376220.
[8] Array Code Examples - PHP Array Functions - PHP
code. http://www.configure-all.com/: Computer Programming Web programming Tips. Retrieved 8 April
2011. In most computer languages array index (counting)
starts from 0, not from 1. Index of the rst element of the
array is 0, index of the second element of the array is 1,
and so on. In array of names below you can see indexes
and values.
[9] Chapter 6 - Arrays, Types, and Constants. Modula-2
Tutorial. http://www.modula2.org/tutor/index.php. Retrieved 8 April 2011. The names of the twelve variables
are given by Automobiles[1], Automobiles[2], ... Automobiles[12]. The variable name is Automobiles and the
array subscripts are the numbers 1 through 12. [i.e. in
Modula-2, the index starts by one!]
[10] Gerald Kruse. CS 240 Lecture Notes: Linked Lists Plus:
Complexity Trade-os. Juniata College. Spring 2008.
[11] Day 1 Keynote - Bjarne Stroustrup: C++11 Style at GoingNative 2012 on channel9.msdn.com from minute 45 or
foil 44
[12] Number crunching: Why you should never, ever, EVER use
linked-list in your code again at kjellkod.wordpress.com
Row-major order
Array slicing
Stride of an array
2.2.7
References
21
then return to using xed-size arrays during program optimization. Resizing the underlying array is an expensive
task, typically involving copying the entire contents of the
array.
27
271
2713
To avoid incurring the cost of resizing many times, dynamic arrays resize by a large amount, such as doubling
in size, and use the reserved space for future expansion.
The operation of adding an element to the end might work
as follows:
27138
271384
Logical size
Capacity
capacity
22
CHAPTER 2. SEQUENCES
Inserting or deleting an element at the end of the namic array data structure, which wastes only n1/2 space
array (constant amortized time)
for n elements at any point in time, and they prove a lower
bound showing that any dynamic array must waste this
Dynamic arrays benet from many of the advantages much space if the operations are to remain amortized
of arrays, including good locality of reference and data constant time. Additionally, they present a variant where
cache utilization, compactness (low memory use), and growing and shrinking the buer has not only amortized
random access. They usually have only a small xed addi- but worst-case constant time.
tional overhead for storing information about the size and
capacity. This makes dynamic arrays an attractive tool
for building cache-friendly data structures. However, in
languages like Python or Java that enforce reference semantics, the dynamic array generally will not store the
actual data, but rather it will store references to the data
that resides in other areas of memory. In this case, accessing items in the array sequentially will actually involve accessing multiple non-contiguous areas of memory, so the many advantages of the cache-friendliness of
this data structure are lost.
Compared to linked lists, dynamic arrays have faster indexing (constant time versus linear time) and typically
faster iteration due to improved locality of reference;
however, dynamic arrays require linear time to insert or
delete at an arbitrary location, since all following elements must be moved, while linked lists can do this in
constant time. This disadvantage is mitigated by the gap
buer and tiered vector variants discussed under Variants
below. Also, in a highly fragmented memory region, it
may be expensive or impossible to nd contiguous space
for a large dynamic array, whereas linked lists do not require the whole data structure to be stored contiguously.
A balanced tree can store a list while providing all operations of both dynamic arrays and linked lists reasonably 2.3.6 References
eciently, but both insertion at the end and iteration over
the list are slower than for a dynamic array, in theory and [1] See, for example, the source code of java.util.ArrayList
class from OpenJDK 6.
in practice, due to non-contiguous storage and tree traversal/manipulation overhead.
2.3.4
Variants
Gap buers are similar to dynamic arrays but allow ecient insertion and deletion operations clustered near the
same arbitrary location. Some deque implementations
use array deques, which allow amortized constant time
insertion/removal at both ends, instead of just one end.
Goodrich[10] presented a dynamic array algorithm called
Tiered Vectors that provided O(n1/2 ) performance for order preserving insertions or deletions from the middle of
the array.
Hashed Array Tree (HAT) is a dynamic array algorithm
published by Sitarski in 1996.[11] Hashed Array Tree
wastes order n1/2 amount of storage space, where n is the
number of elements in the array. The algorithm has O(1)
amortized performance when appending a series of objects to the end of a Hashed Array Tree.
In a 1999 paper,[9] Brodnik et al. describe a tiered dy-
[2] Lambert, Kenneth Alfred (2009), Physical size and logical size, Fundamentals of Python: From First Programs
Through Data Structures (Cengage Learning): 510, ISBN
1423902181
[3] Goodrich, Michael T.; Tamassia, Roberto (2002), 1.5.2
Analyzing an Extendable Array Implementation, Algorithm Design: Foundations, Analysis and Internet Examples, Wiley, pp. 3941.
[4] Cormen, Thomas H.; Leiserson, Charles E., Rivest,
Ronald L., Stein, Cliord (2001) [1990]. 17.4 Dynamic
tables. Introduction to Algorithms (2nd ed.). MIT Press
and McGraw-Hill. pp. 416424. ISBN 0-262-03293-7.
[5] List object implementation from python.org, retrieved
2011-09-27.
[6] Gerald Kruse. CS 240 Lecture Notes: Linked Lists Plus:
Complexity Trade-os. Juniata College. Spring 2008.
[7] Day 1 Keynote - Bjarne Stroustrup: C++11 Style at GoingNative 2012 on channel9.msdn.com from minute 45 or
foil 44
[8] Number crunching: Why you should never, ever, EVER use
linked-list in your code again at kjellkod.wordpress.com
[9] Brodnik, Andrej; Carlsson, Svante; Sedgewick, Robert;
Munro, JI; Demaine, ED (1999), Resizable Arrays in Optimal Time and Space (Technical Report CS-99-09), Department of Computer Science, University of Waterloo
[10] Goodrich, Michael T.; Kloss II, John G. (1999), Tiered
Vectors: Ecient Dynamic Arrays for Rank-Based
Sequences, Workshop on Algorithms and Data Structures, Lecture Notes in Computer Science 1663: 205
216, doi:10.1007/3-540-48447-7_21, ISBN 978-3-54066279-2
[11] Sitarski, Edward (September 1996), HATs: Hashed array trees, Dr. Dobbs Journal 21 (11) |chapter= ignored
(help)
[12] Bagwell, Phil (2002), Fast Functional Lists, Hash-Lists,
Deques and Variable Length Arrays, EPFL
[13] Javadoc on ArrayList
2.3.7
External links
23
Chapter 3
Dictionaries
3.1 Associative array
Dictionary (data structure)" redirects here. It is not to
be confused with data dictionary.
In addition, associative arrays may also include other operations such as determining the number of bindings or
constructing an iterator to loop over all the bindings. Usually, for such an operation, the order in which the bindings
are returned may be arbitrary.
A multimap generalizes an associative array by allowing
multiple values to be associated with a single key.[6] A
bidirectional map is a related abstract data type in which
the bindings operate in both directions: each value must
be associated with a unique key, and a second lookup operation takes a value as argument and looks up the key
associated with that value.
3.1.1
Operations
Example
24
25
Language support
modern scripting languages, starting with AWK and including Rexx, Perl, Tcl, JavaScript, Python, Ruby, and
Lua, support associative arrays as a primary container
type. In many more languages, they are available as library functions without special syntax.
In Smalltalk, Objective-C, .NET,[8] Python, REALbasic,
and Swift they are called dictionaries; in Perl, Ruby and
Seed7 they are called hashes; in C++, Java, Go, Clojure,
Scala, OCaml, Haskell they are called maps (see map
(C++), unordered_map (C++), and Map); in Common
Lisp and Windows PowerShell, they are called hash tables (since both typically use this implementation). In
PHP, all arrays can be associative, except that the keys
are limited to integers and strings. In JavaScript (see also
JSON), all objects behave as associative arrays. In Lua,
they are called tables, and are used as the primitive building block for all data structures. In Visual FoxPro, they
are called Collections. The D language also has support
for associative arrays [9]
The most frequently used general purpose implementation of an associative array is with a hash table: an array
of bindings, together with a hash function that maps each
possible key into an array index. The basic idea of a hash
table is that the binding for a given key is stored at the position given by applying the hash function to that key, and
that lookup operations are performed by looking at that
cell of the array and using the binding found there. However, hash table based dictionaries must be prepared to
handle collisions that occur when two keys are mapped
by the hash function to the same index, and many different collision resolution strategies have been developed 3.1.5 See also
for dealing with this situation, often based either on open
Tuple
addressing (looking at a sequence of hash table indices instead of a single index, until nding either the given key
Function (mathematics)
or an empty cell) or on hash chaining (storing a small association list instead of a single binding in each hash table
Key-value data store
26
CHAPTER 3. DICTIONARIES
JSON
3.1.6
References
3.2.1 References
[1] McCarthy, John; Abrahams, Paul W.; Edwards, Daniel
J.; Hart, Timothy P.; Levin, Michael I. (1985). LISP 1.5
Programmers Manual. MIT Press. ISBN 0-262-130114.
keys
hash
function
buckets
00
3.1.7
External links
John Smith
Lisa Smith
Sandra Dee
01
521-8976
02
521-1234
03
:
13
14
521-9655
15
3.3.1
27
ate if there is a risk of malicious users trying to sabotage
a network service by submitting requests designed to generate a large number of collisions in the servers hash tables. However, the risk of sabotage can also be avoided
by cheaper methods (such as applying a secret salt to the
data, or using a universal hash function).
Hashing
Perfect hash function
Key statistics
A critical statistic for a hash table is called the load factor. This is simply the number of entries divided by the
number of buckets, that is, n/k where n is the number of
entries and k is the number of buckets.
If the load factor is kept reasonable, the hash table should
perform well, provided the hashing is good. If the load
factor grows too large, the hash table will become slow,
or it may fail to work (depending on the method used).
The expected constant time property of a hash table assumes that the load factor is kept below some bound. For
a xed number of buckets, the time for a lookup grows
with the number of entries and so does not achieve the
desired constant time.
28
CHAPTER 3. DICTIONARIES
keys
buckets
000
John Smith
Lisa Smith
Sam Doe
Sandra Dee
Ted Baker
001
entries
Lisa Smith
521-8976
John Smith
521-1234
Sandra Dee
521-9655
Ted Baker
418-4165
Sam Doe
521-5030
002
:
151
152
153
154
:
253
254
255
In a good hash table, each bucket has zero or one entries, and sometimes two or three, but rarely more than
that. Therefore, structures that are ecient in time and
space for these cases are preferred. Structures that are efcient for a fairly large number of entries per bucket are
not needed or desirable. If these cases happen often, the
hashing is not working well, and this needs to be xed.
entries
buckets
000
John Smith
Lisa Smith
Sam Doe
Sandra Dee
Ted Baker
001
Lisa Smith
521-8976
002
:
152
John Smith
521-1234
153
Ted Baker
418-4165
Sam Doe
521-5030
151
Sandra Dee
521-9655
154
:
253
254
255
Separate chaining with linked lists Chained hash ta- bucket array.
bles with linked lists are popular because they require
only basic data structures with simple algorithms, and can
Separate chaining with list head cells Some chaining
use simple hash functions that are unsuitable for other
implementations store the rst record of each chain in the
methods.
slot array itself.[4] The number of pointer traversals is deThe cost of a table operation is that of scanning the entries creased by one for most cases. The purpose is to increase
of the selected bucket for the desired key. If the distribu- cache eciency of hash table access.
tion of keys is suciently uniform, the average cost of a
The disadvantage is that an empty bucket takes the same
lookup depends only on the average number of keys per
space as a bucket with one entry. To save space, such hash
bucketthat is, on the load factor.
tables often have about as many slots as stored entries,
Chained hash tables remain eective even when the num- meaning that many slots have two or more entries.
ber of table entries n is much higher than the number of
slots. Their performance degrades more gracefully (linearly) with the load factor. For example, a chained hash Separate chaining with other structures Instead of
table with 1000 slots and 10,000 stored keys (load fac- a list, one can use any other data structure that supports
tor 10) is ve to ten times slower than a 10,000-slot table the required operations. For example, by using a self(load factor 1); but still 1000 times faster than a plain se- balancing tree, the theoretical worst-case time of common hash table operations (insertion, deletion, lookup)
quential list.
29
can be brought down to O(log n) rather than O(n). However, this approach is only worth the trouble and extra
memory cost if long delays must be avoided at all costs
(e.g., in a real-time application), or if one must guard
against many entries hashed to the same slot (e.g., if one
expects extremely non-uniform distributions, or in the
case of web sites or other publicly accessible services,
which are vulnerable to malicious key distributions in requests).
keys
buckets
000
001
Lisa Smith
521-8976
152
John Smith
521-1234
153
Sandra Dee
521-9655
154
Ted Baker
418-4165
Sam Doe
521-5030
John Smith
002
Lisa Smith
151
Sam Doe
Sandra Dee
155
:
253
254
30
CHAPTER 3. DICTIONARIES
function is used, and so on. If a collision happens during
insertion, then the key is re-hashed with the second hash
function to map it to another bucket. If all hash functions are used and there is still a collision, then the key it
collided with is removed to make space for the new key,
and the old key is re-hashed with one of the other hash
functions, which maps it to another bucket. If that location also results in a collision, then the process repeats
until there is no collision or the process traverses all the
buckets, at which point the table is resized. By combining multiple hash functions with multiple cells per bucket,
very high space utilisation can be achieved.
This graph compares the average number of cache misses required to look up elements in tables with chaining and linear
probing. As the table passes the 80%-full mark, linear probings
performance drastically degrades.
31
For hash tables that shrink and grow frequently, the resizing downward can be skipped entirely. In this case, the table size is proportional to the number of entries that ever
were in the hash table, rather than the current number.
The disadvantage is that memory usage will be higher,
and thus cache behavior may be worse. For best control,
a shrink-to-t operation can be provided that does this
only on request.
If the table size increases or decreases by a xed percentage at each expansion, the total cost of these resizings,
3.3.4 Dynamic resizing
amortized over all insert and delete operations, is still a
constant, independent of the number of entries n and of
The good functioning of a hash table depends on the fact the number m of operations performed.
that the table size is proportional to the number of entries. For example, consider a table that was created with the
With a xed size, and the common structures, it is simi- minimum possible size and is doubled each time the load
lar to linear search, except with a better constant factor. ratio exceeds some threshold. If m elements are inserted
In some cases, the number of entries may be denitely into that table, the total number of extra re-insertions that
known in advance, for example keywords in a language. occur in all dynamic resizings of the table is at most m
More commonly, this is not known for sure, if only due 1. In other words, dynamic resizing roughly doubles the
to later changes in code and data. It is one serious, al- cost of each insert or delete operation.
though common, mistake to not provide any way for the
table to resize. A general-purpose hash table class will
almost always have some way to resize, and it is good Incremental resizing
practice even for simple custom tables. An implementation should check the load factor, and do something if it Some hash table implementations, notably in real-time
becomes too large (this needs to be done only on inserts, systems, cannot pay the price of enlarging the hash table
since that is the only thing that would increase it).
all at once, because it may interrupt time-critical operaTo keep the load factor under a certain limit, e.g., under tions. If one cannot avoid dynamic resizing, a solution is
3/4, many table implementations expand the table when to perform the resizing gradually:
items are inserted. For example, in Javas HashMap class
the default load factor threshold for table expansion is
0.75 and in Pythons dict, table size is resized when load
factor is greater than 2/3.
32
CHAPTER 3. DICTIONARIES
Monotonic keys
If it is known that key values will always increase (or
decrease) monotonically, then a variation of consistent
hashing can be achieved by keeping a list of the single
most recent key value at each hash table resize operation.
Upon lookup, keys that fall in the ranges dened by these
list entries are directed to the appropriate hash function
and indeed hash tableboth of which can be dierent for
each range. Since it is common to grow the overall number of entries by doubling, there will only be O(lg(N))
ranges to check, and binary search time for the redirection would be O(lg(lg(N))). As with consistent hashing,
this approach guarantees that any keys hash, once issued,
will never change, even when the hash table is later grown.
Other solutions
3.3.6 Features
Advantages
The main advantage of hash tables over other table data
structures is speed. This advantage is more apparent
when the number of entries is large. Hash tables are particularly ecient when the maximum number of entries
can be predicted in advance, so that the bucket array can
be allocated once with the optimum size and never resized.
3.3.5
Performance analysis
In the simplest model, the hash function is completely unspecied and the table does not resize. For the best possible choice of hash function, a table of size k with open
addressing has no collisions and holds up to k elements,
with a single comparison for successful lookup, and a table of size k with chaining and n keys has the minimum
max(0, n-k) collisions and O(1 + n/k) comparisons for
lookup. For the worst choice of hash function, every insertion causes a collision, and hash tables degenerate to
linear search, with (n) amortized comparisons per insertion and up to n comparisons for a successful lookup.
For certain string processing applications, such as spellchecking, hash tables may be less ecient than tries, nite
automata, or Judy arrays. Also, if each key is represented
by a small enough number of bits, then, instead of a hash
table, one may use the key directly as the index into an
Adding rehashing to this model is straightforward. As in array of values. Note that there are no collisions in this
a dynamic array, geometric resizing by a factor of b im- case.
plies that only n/bi keys are inserted i or more times, so The entries stored in a hash table can be enumerated efthat the total number of insertions is bounded above by ciently (at constant cost per entry), but only in some
bn/(b1), which is O(n). By using rehashing to maintain pseudo-random order. Therefore, there is no ecient
n < k, tables using both chaining and open addressing can way to locate an entry whose key is nearest to a given key.
have unlimited elements and perform successful lookup Listing all n entries in some specic order generally rein a single comparison for the best choice of hash func- quires a separate sorting step, whose cost is proportional
tion.
to log(n) per entry. In comparison, ordered search trees
In more realistic models, the hash function is a random have lookup and insertion cost proportional to log(n), but
variable over a probability distribution of hash functions, allow nding the nearest key at about the same cost, and
and performance is computed on average over the choice ordered enumeration of all entries at constant cost per enof hash function. When this distribution is uniform, the try.
assumption is called simple uniform hashing and it can If the keys are not stored (because the hash function is
33
3.3.7
Uses
Associative arrays
Object representation
Several dynamic languages, such as Perl, Python,
JavaScript, and Ruby, use hash tables to implement objects. In this representation, the keys are the names of the
members and methods of the object, and the values are
pointers to the corresponding member or method.
Unique data representation
Hash tables can be used by some programs to avoid creating multiple character strings with the same contents.
For that purpose, all strings in use by the program are
stored in a single string pool implemented as a hash table,
which is checked whenever a new string has to be created.
This technique was introduced in Lisp interpreters under
When storing a new item into a multimap and a hash col- the name hash consing, and can be used with many other
lision occurs, the multimap unconditionally stores both kinds of data (expression trees in a symbolic algebra system, records in a database, les in a le system, binary
items.
decision diagrams, etc.)
When storing a new item into a typical associative array
and a hash collision occurs, but the actual keys themselves are dierent, the associative array likewise stores String interning
both items. However, if the key of the new item exactly
matches the key of an old item, the associative array typ- Main article: String interning
ically erases the old item and overwrites it with the new
item, so every item in the table has a unique key.
3.3.8 Implementations
Database indexing
In programming languages
Hash tables may also be used as disk-based data structures
and database indices (such as in dbm) although B-trees Many programming languages provide hash table funcare more popular in these applications.
tionality, either as built-in associative arrays or as stan-
34
CHAPTER 3. DICTIONARIES
Stable hashing
In PHP 5, the Zend 2 engine uses one of the hash functions from Daniel J. Bernstein to generate the hash values
used in managing the mappings of data pointers stored
in a hash table. In the PHP source code, it is labelled as
DJBX33A (Daniel J. Bernstein, Times 33 with Addition).
Extendible hashing
Consistent hashing
Lazy deletion
Pearson hashing
PhotoDNA
Python's built-in hash table implementation, in the form
of the dict type, as well as Perl's hash type (%) are used
internally to implement namespaces and therefore need Related data structures
to pay more attention to security, i.e., collision attacks.
Python sets also use hashes internally, for fast lookup There are several data structures that use hash functions
(though they store only keys, not values).[24]
but cannot be considered special cases of hash tables:
In the .NET Framework, support for hash tables is provided via the non-generic Hashtable and generic Dictio Bloom lter, memory ecient data-structure denary classes, which store key-value pairs, and the generic
signed for constant-time approximate lookups; uses
HashSet class, which stores only values.
hash function(s) and can be seen as an approximate
hash table.
Independent packages
SparseHash (formerly Google SparseHash) An extremely memory-ecient hash_map implementa Hash array mapped trie, a trie structure, similar to
tion, with only 2 bits/entry of overhead. The Sparsethe array mapped trie, but where each key is hashed
Hash library has several C++ hash map implementarst.
tions with dierent performance characteristics, including one that optimizes for memory use and an3.3.11 References
other that optimizes for speed.
SunriseDD An open source C library for hash table storage of arbitrary data objects with lock-free
lookups, built-in reference counting and guaranteed
order iteration. The library can participate in external reference counting systems or use its own
built-in reference counting. It comes with a variety of hash functions and allows the use of runtime supplied hash functions via callback mechanism. Source code is well documented.
uthash This is an easy-to-use hash table for C structures.
3.3.9
History
3.3.10
See also
35
[8] Askitis, Nikolas; Zobel, Justin (October 2005). Cacheconscious Collision Resolution in String Hash Tables. Proceedings of the 12th International Conference, String
Processing and Information Retrieval (SPIRE 2005).
3772/2005. pp. 91102. doi:10.1007/11575832_11.
ISBN 978-3-540-29740-6.
[24] http://stackoverflow.com/questions/513882/
python-list-vs-dict-for-look-up-table
[25] Mehta, Dinesh P.; Sahni, Sartaj. Handbook of Datastructures and Applications. pp. 915. ISBN 1-58488-435-5.
36
CHAPTER 3. DICTIONARIES
strictly less than one.[2] This analysis makes the (unrealistic) assumption that the hash function is completely
Linear probing is a scheme in computer programming random, but can be extended also to 5-independent hash
[3]
for resolving hash collisions of values of hash functions by functions. Weaker properties, such as universal hashsequentially searching the hash table for a free location.[1] ing, are not strong enough to ensure the constant-time operation of linear probing,[4] but one practical method of
hash function generation, tabulation hashing, again leads
to a guaranteed constant expected time performance de3.4.1 Algorithm
spite not being 5-independent.[5]
Linear probing is accomplished using two values - one as
a starting value and one as an interval between successive
values in modular arithmetic. The second value, which is 3.4.4 See also
the same for all keys and known as the stepsize, is repeat Quadratic probing
edly added to the starting value until a free space is found,
or the entire table is traversed. (In order to traverse the
Collision resolution
entire table the stepsize should be relatively prime to the
arraysize, which is why the array size is often chosen to
be a prime number.)
3.4.5 References
newLocation = (startingValue +
stepSize) % arraySize
Given an ordinary hash function H(x), a linear probing
function (H(x, i)) would be:
3.4.2
Properties
This algorithm, which is used in open-addressed hash tables, provides good memory caching (if stepsize is equal
to one), through good locality of reference, but also re- 3.4.6 External links
sults in clustering, an unfortunately high probability that
where there has been one collision there will be more.
How Caching Aects Hashing by Gregory L. HeileThe performance of linear probing is also more sensitive
man and Wenbin Luo 2005.
to input distribution when compared to double hashing,
Open Data Structures - Section 5.2 - Linwhere the stepsize is determined by another hash function
earHashTable: Linear Probing
applied to the value instead of a xed stepsize as in linear
probing.
3.4.3
Using linear probing, dictionary operation can be implemented in constant time. In other words, insert, remove
and search operations can be implemented in O(1), as
long as the load factor of the hash table is a constant
Chapter 4
37
38
Eppstein, User A1, Maju wiki, 2help, Cometstyles, The Wilschon, BotKung, Groupthink, Keilana, Xe7al, Ykhwong, Alastair Carnegie,
Ivan Akira, Roux, Jarble, Legobot, Yobot, Fraggle81, Pcap, GateKeeper, AnomieBOT, Materialscientist, Miym, Charvest, Fortdj33,
124Nick, RobinK, WillNess, RjwilmsiBot, Uploader4u, Jmencisom, Wikipelli, The Nut, Tirab, Tijfo098, ClueBot NG, Ifarzana, Satellizer,
Tvguide1234, Helpful Pixie Bot, Intr199, Manuel.mas12, Liam987, AlexanderZoul, Jochen Burghardt, Cubism44, Vieque and Anonymous:
74
Array data type Source: http://en.wikipedia.org/wiki/Array%20data%20type?oldid=634958546 Contributors: Edward, Michael Hardy,
Jorge Stol, Beland, D6, Spoon!, Bgwhite, RussBot, KGasso, SmackBot, Canthusus, Nbarth, Cybercobra, Lambiam, Korval, Hvn0413,
Mike Fikes, JohnCaron, Hroulf, Vigyani, Cerberus0, Kbrose, ClueBot, Mxaza, Garyzx, Staticshakedown, Addbot, Yobot, Denispir, Pcap,
AnomieBOT, Jim1138, Praba230890, Nhantdn, Termininja, Akhilan, Thecheesykid, Cgtdk, ClueBot NG, Mariuskempe, Helpful Pixie
Bot, Airatique, Pratyya Ghosh, Soni, Yamaha5 and Anonymous: 39
Array data structure Source: http://en.wikipedia.org/wiki/Array%20data%20structure?oldid=644965427 Contributors: The Anome, Ed
Poor, Andre Engels, Tsja, B4hand, Patrick, RTC, Michael Hardy, Norm, Nixdorf, Graue, TakuyaMurata, Alo, Ellywa, Julesd, Cgs, Poor
Yorick, Rossami, Dcoetzee, Dysprosia, Jogloran, Wernher, Fvw, Sewing, Robbot, Josh Cherry, Fredrik, Lowellian, Wikibot, Jleedev,
Giftlite, DavidCary, Massysett, BenFrantzDale, Lardarse, Ssd, Jorge Stol, Macrakis, Jonathan Grynspan, Lockeownzj00, Beland, Vanished user 1234567890, Karol Langner, Icairns, Simoneau, Jh51681, Andreas Kaufmann, Mattb90, Corti, Jkl, Rich Farmbrough, Guanabot,
Qutezuce, ESkog, ZeroOne, Danakil, MisterSheik, G worroll, Spoon!, Army1987, Func, Rbj, Mdd, Jumbuck, Mr Adequate, Atanamir,
Krischik, Tauwasser, ReyBrujo, Suruena, Rgrig, Forderud, Beliavsky, Beej71, Mindmatrix, Jimbryho, Ruud Koot, Je3000, Grika, Palica,
Gerbrant, Graham87, Kbdank71, Zzedar, Ketiltrout, Bill37212, Ligulem, Yamamoto Ichiro, Mike Van Emmerik, Quuxplusone, Intgr,
Visor, Sharkface217, Bgwhite, YurikBot, Wavelength, Borgx, RobotE, RussBot, Fabartus, Splash, Piet Delport, Stephenb, Pseudomonas,
Kimchi.sg, Dmason, JulesH, Mikeblas, Bota47, JLaTondre, Hide&Reason, Heavyrain2408, SmackBot, Princeatapi, Blue520, Trojo, Brick
Thrower, Alksub, Apers0n, Betacommand, GwydionM, Anwar saadat, Keegan, Timneu22, Mcaruso, Tsca.bot, Tamfang, Berland, Cybercobra, Mwtoews, Masterdriverz, Kukini, Smremde, SashatoBot, Derek farn, John, 16@r, Slakr, Beetstra, Dreftymac, Courcelles,
George100, Ahy1, Engelec, Wws, Neelix, Simeon, Kaldosh, Travelbird, Mrstonky, Skittleys, Strangelv, Christian75, Narayanese, Epbr123,
Sagaciousuk, Trevyn, Escarbot, Thadius856, AntiVandalBot, AbstractClass, JAnDbot, JaK81600, Cameltrader, PhiLho, SiobhanHansa,
Magioladitis, VoABot II, Ling.Nut, DAGwyn, David Eppstein, User A1, Squidonius, Gwern, Highegg, Themania, Patar knight, J.delanoy,
Slogsweep, Darkspots, Jayden54, Mfb52, Funandtrvl, VolkovBot, TXiKiBoT, Anonymous Dissident, Don4of4, Amog, Redacteur, Nicvaroce, Kbrose, SieBot, Caltas, Garde, Tiptoety, Paolo.dL, Oxymoron83, Svick, Anchor Link Bot, Jlmerrill, ClueBot, LAX, Jackollie,
The Thing That Should Not Be, Alksentrs, Rilak, Supertouch, R000t, Liempt, Excirial, Immortal Wowbagger, Bargomm, Thingg, Footballfan190, Johnuniq, SoxBot III, Awbell, Chris glenne, Staticshakedown, SilvonenBot, Henrry513414, Dsimic, Gaydudes, Btx40, EconoPhysicist, SamatBot, Zorrobot, Legobot, Luckas-bot, Yobot, Ptbotgourou, Fraggle81, Peter Flass, Tempodivalse, Obersachsebot, Xqbot,
SPTWriter, FrescoBot, Citation bot 2, I dream of horses, HRoestBot, MastiBot, Jandalhandler, Laureniu Dasclu, Dinamik-bot, TylerWilliamRoss, Merlinsorca, Jfmantis, The Utahraptor, EmausBot, Mfaheem007, Donner60, Ipsign, Ieee andy, EdoBot, Muzadded, Mikhail
Ryazanov, ClueBot NG, Widr, Helpful Pixie Bot, Roger Wellington-Oguri, Wbm1058, 111008066it, Mark Arsten, Simba2331, Insidiae,
ChrisGualtieri, A'bad group, Makecat-bot, Chetan chopade, Ginsuloft and Anonymous: 238
Dynamic array Source: http://en.wikipedia.org/wiki/Dynamic%20array?oldid=635160619 Contributors: Damian Yerrick, Edward,
Ixfd64, Phoe6, Dcoetzee, Furrykef, Wdscxsj, Jorge Stol, Karol Langner, Andreas Kaufmann, Moxfyre, Dpm64, Wrp103, Forbsey, ZeroOne, MisterSheik, Spoon!, Ryk, Fresheneesz, Wavelength, SmackBot, Rnin, Bluebot, Octahedron80, Nbarth, Cybercobra, Decltype,
MegaHasher, Beetstra, Green caterpillar, Icep, Wikilolo, David Eppstein, Gwern, Cobi, Spinningspark, Arbor to SJ, Ctxppc, ClueBot, Simonykill, Garyzx, Alex.vatchenko, Addbot, AndersBot, , Aekton, Didz93, Tartarus, Luckas-bot, Yobot, , Rubinbot, Citation bot,
SPTWriter, FrescoBot, Mutinus, Patmorin, WillNess, EmausBot, Card Zero, Franois Robere and Anonymous: 38
Associative array Source: http://en.wikipedia.org/wiki/Associative%20array?oldid=644061854 Contributors: Damian Yerrick, Robert
Merkel, Fubar Obfusco, Maury Markowitz, Hirzel, B4hand, Paul Ebermann, Edward, Patrick, Michael Hardy, Shellreef, Graue,
Minesweeper, Brianiac, Samuelsen, Bart Massey, Hashar, Dcoetzee, Dysprosia, Silvonen, Bevo, Robbot, Noldoaran, Fredrik, Altenmann,
Wlievens, Catbar, Wikibot, Ruakh, EvanED, Jleedev, Tobias Bergemann, Ancheta Wis, Jpo, DavidCary, Mintleaf, Inter, Wolfkeeper,
Jorge Stol, Macrakis, Pne, Neilc, Kusunose, Karol Langner, Bosmon, Int19h, Andreas Kaufmann, RevRagnarok, Ericamick, LeeHunter,
PP Jewel, Kwamikagami, James b crocker, Spoon!, Bobo192, TommyG, Minghong, Alansohn, Mt, Krischik, Sligocki, Kdau, Tony Sidaway, RainbowOfLight, Forderud, TShilo12, Boothy443, Mindmatrix, RzR, Apokrif, Kglavin, Bluemoose, ObsidianOrder, Pfunk42,
Yurik, Swmcd, Scandum, Koavf, Agorf, Je02, RexNL, Alvin-cs, Wavelength, Fdb, Maerk, Dggoldst, Cedar101, JLaTondre, Ffangs,
TuukkaH, SmackBot, KnowledgeOfSelf, MeiStone, Mirzabah, TheDoctor10, Sam Pointon, Brianski, Hugo-cs, Jdh30, Zven, Cfallin,
CheesyPus144, Malbrain, Nick Levine, Vegard, Radagast83, Cybercobra, Decltype, Paddy3118, AvramYU, Doug Bell, AmiDaniel, Antonielly, EdC, Tobe2199, Hans Bauer, Dreftymac, Pimlottc, George100, JForget, Jokes Free4Me, Pgr94, MrSteve, Countchoc, Ajo Mama,
WinBot, Oddity-, Alphachimpbot, Maslin, JonathanCross, Pfast, PhiLho, Wmbolle, Magioladitis, David Eppstein, Gwern, Doc aberdeen,
Signalhead, VolkovBot, Chaos5023, Kyle the bot, TXiKiBoT, Anna Lincoln, BotKung, Comet--berkeley, Jesdisciple, PanagosTheOther,
Nemo20000, Jerryobject, CultureDrone, Anchor Link Bot, ClueBot, Irishjugg, XLinkBot, Orbnauticus, Frostus, Dsimic, Deineka, Addbot,
Debresser, Jarble, Bartledan, Davidwhite544, Margin1522, Legobot, Luckas-bot, Yobot, TaBOT-zerem, Pcap, Peter Flass, RibotBOT, January2009, Sae1962, Efadae, Neil Schipper, Floatingdecimal, Tushar858, EmausBot, WikitanvirBot, Marcos canbeiro, AvicBot, ClueBot
NG, JannuBl22t, Helpful Pixie Bot, Mithrasgregoriae, JYBot, Dcsaba70, Alonsoguillenv and Anonymous: 187
Association list Source: http://en.wikipedia.org/wiki/Association%20list?oldid=547284302 Contributors: SJK, Dcoetzee, Dremora, Tony
Sidaway, Pmcjones, Yobot, Helpful Pixie Bot and Anonymous: 2
Hash table Source: http://en.wikipedia.org/wiki/Hash%20table?oldid=645193336 Contributors: Damian Yerrick, AxelBoldt, Zundark,
The Anome, BlckKnght, Sandos, Rgamble, LapoLuchini, AdamRetchless, Imran, Mrwojo, Frecklefoot, Michael Hardy, Nixdorf, Pnm,
Axlrosen, TakuyaMurata, Ahoerstemeier, Nanshu, Dcoetzee, Dysprosia, Furrykef, Omegatron, Wernher, Bevo, Tjdw, Pakaran, Secretlondon, Robbot, Fredrik, Tomchiukc, R3m0t, Altenmann, Ashwin, UtherSRG, Miles, Giftlite, DavidCary, Wolfkeeper, BenFrantzDale,
Everyking, Waltpohl, Jorge Stol, Wmahan, Neilc, Pgan002, CryptoDerk, Knutux, Bug, Sonjaaa, Teacup, Beland, Watcher, DNewhall,
ReiniUrban, Sam Hocevar, Derek Parnell, Askewchan, Kogorman, Andreas Kaufmann, Kaustuv, Shuchung, T Long, Hydrox, Cfailde,
Luqui, Wrp103, Antaeus Feldspar, Khalid, Raph Levien, JustinWick, CanisRufus, Shanes, Iron Wallaby, Krakhan, Bobo192, Davidgothberg, Larry V, Sleske, Helix84, Mdd, Varuna, Baka toroi, Anthony Appleyard, Sligocki, Drbreznjev, DSatz, Akuchling, TShilo12, Nuno
Tavares, Woohookitty, LOL, Linguica, Paul Mackay, Davidfstr, GregorB, Meneth, Kbdank71, Tostie14, Rjwilmsi, Scandum, Koavf, Kinu,
Filu, Nneonneo, FlaBot, Ecb29, Fragglet, Intgr, Fresheneesz, Antaeus FeIdspar, YurikBot, Wavelength, RobotE, Mongol, RussBot, Me
and, CesarBs unpriviledged account, Lavenderbunny, Gustavb, Mipadi, Cryptoid, Mike.aizatsky, Gareth Jones, Piccolomomo, CecilWard,
Nethgirb, Gadget850, Bota47, Sebleblanc, Deeday-UK, Sycomonkey, Ninly, Gulliveig, Th1rt3en, CWenger, JLaTondre, ASchmoo, Kungfuadam, SmackBot, Apanag, Obakeneko, PizzaMargherita, Alksub, Eskimbot, RobotJcb, C4chandu, Arpitm, Neurodivergent, EncMstr,
4.2. IMAGES
39
Cribe, Deshraj, Tackline, Frap, Mayrel, Radagast83, Cybercobra, Decltype, HFuruseth, Rich.lewis, Esb, Acdx, MegaHasher, Doug Bell,
Derek farn, IronGargoyle, Josephsieh, Peter Horn, Pagh, Saxton, Tawkerbot2, Ouishoebean, CRGreathouse, Ahy1, MaxEnt, Seizethedave, Cgma, Not-just-yeti, Thermon, OtterSmith, Ajo Mama, Stannered, AntiVandalBot, Hosamaly, Thailyn, Pixor, JAnDbot, MER-C,
Epeeeche, Dmbstudio, SiobhanHansa, Wikilolo, Bongwarrior, QrczakMK, Josephskeller, Tedickey, Schwarzbichler, Cic, Allstarecho,
David Eppstein, Oravec, Gwern, Magnus Bakken, Glrx, Narendrak, Tikiwont, Mike.lifeguard, Luxem, NewEnglandYankee, Cobi, Cometstyles, Winecellar, VolkovBot, Simulationelson, Floodyberry, Anurmi, BotKung, Collin Stocks, JimJJewett, Nightkhaos, Spinningspark,
Abatishchev, Helios2k6, Kehrbykid, Kbrose, PeterCanthropus, Gerakibot, Triwbe, Digwuren, Svick, JL-Bot, ObfuscatePenguin, ClueBot,
Justin W Smith, Adrianwn, Mild Bill Hiccup, Niceguyedc, JJuran, Groxx, Berean Hunter, Eddof13, Johnuniq, Arlolra, XLinkBot, Hetori,
Pichpich, Paulsheer, TheTraveler3, MystBot, Karuthedam, Wolkykim, Addbot, Gremel123, CanadianLinuxUser, MrOllie, Numbo3-bot,
Om Sao, Zorrobot, Jarble, Frehley, Legobot, Luckas-bot, Yobot, Denispir, KamikazeBot, Dmcomer, AnomieBOT, Erel Segal, Jim1138,
Sz-iwbot, Citation bot, ArthurBot, Baliame, Drilnoth, Arbalest Mike, Ched, Shadowjams, Kracekumar, FrescoBot, W Nowicki, X7q,
Sae1962, Citation bot 1, Velociostrich, Simonsarris, Iekpo, Trappist the monk, SchreyP, Grapesoda22, Patmorin, Cutelyaware, JeepdaySock, Shagoldwasser, Kastchei, DuineSidhe, EmausBot, Super48paul, Ibbn, DanielWaterworth, Mousehousemd, ZroBot, Purplie,
Ticklemepink42, Paul Kube, Demonkoryu, Donner60, Carmichael, Pheartheceal, Aberdeen01, Teapeat, Rememberway, ClueBot NG, AznBurger, Incompetence, Rawafmail, Cntras, Rezabot, Jk2q3jrklse, Helpful Pixie Bot, Jan Spousta, MusikAnimal, SanAnMan, Pbruneau,
AdventurousSquirrel, Triston J. Taylor, CitationCleanerBot, Happyuk, FeralOink, Spacemanaki, Aloksukhwani, Emimull, Deveedutta,
Shmageggy, IgushevEdward, AlecTaylor, Mcom320, Razibot, Djszapi, QuantiedElf, Chip Wildon Forster, Tmferrara, Tuketu7, Monkbot,
Iokevins, Oleaster and Anonymous: 423
Linear probing Source: http://en.wikipedia.org/wiki/Linear%20probing?oldid=636374192 Contributors: Ubiquity, Bearcat, Enochlau,
Andreas Kaufmann, Gazpacho, Discospinster, RJFJR, Linas, Tas50, CesarBs unpriviledged account, SpuriousQ, Chris the speller, JonHarder, MichaelBillington, Sbluen, Jeberle, Negrulio, Jngnyc, Alaibot, Thijs!bot, A3nm, David Eppstein, STBot, Themania, OliviaGuest,
C. A. Russell, Addbot, Tedzdog, Patmorin, Innity ive, Dixtosa, Danmoberly and Anonymous: 15
4.2 Images
File:8bit-dynamiclist.gif Source: http://upload.wikimedia.org/wikipedia/commons/1/1d/8bit-dynamiclist.gif License: CC-BY-SA-3.0
Contributors: Own work Original artist: Seahen
File:Array_of_array_storage.svg Source: http://upload.wikimedia.org/wikipedia/commons/0/01/Array_of_array_storage.svg License:
Public domain Contributors: ? Original artist: ?
File:Commons-logo.svg Source: http://upload.wikimedia.org/wikipedia/en/4/4a/Commons-logo.svg License: ? Contributors: ? Original
artist: ?
File:Dynamic_array.svg Source: http://upload.wikimedia.org/wikipedia/commons/3/31/Dynamic_array.svg License: CC0 Contributors:
Own work Original artist: Dcoetzee
File:Hash_table_3_1_1_0_1_0_0_SP.svg Source: http://upload.wikimedia.org/wikipedia/commons/7/7d/Hash_table_3_1_1_0_1_0_
0_SP.svg License: CC BY-SA 3.0 Contributors: Own work Original artist: Jorge Stol
File:Hash_table_5_0_1_1_1_1_0_LL.svg Source: http://upload.wikimedia.org/wikipedia/commons/5/5a/Hash_table_5_0_1_1_1_1_
0_LL.svg License: CC BY-SA 3.0 Contributors: Own work Original artist: Jorge Stol
File:Hash_table_5_0_1_1_1_1_0_SP.svg Source: http://upload.wikimedia.org/wikipedia/commons/b/bf/Hash_table_5_0_1_1_1_1_0_
SP.svg License: CC BY-SA 3.0 Contributors: Own work Original artist: Jorge Stol
File:Hash_table_5_0_1_1_1_1_1_LL.svg Source: http://upload.wikimedia.org/wikipedia/commons/d/d0/Hash_table_5_0_1_1_1_1_
1_LL.svg License: CC BY-SA 3.0 Contributors: Own work Original artist: Jorge Stol
File:Hash_table_average_insertion_time.png Source: http://upload.wikimedia.org/wikipedia/commons/1/1c/Hash_table_average_
insertion_time.png License: Public domain Contributors: Authors Own Work. Original artist: Derrick Coetzee (User:Dcoetzee)
File:LampFlowchart.svg Source: http://upload.wikimedia.org/wikipedia/commons/9/91/LampFlowchart.svg License: CC-BY-SA-3.0
Contributors: vector version of Image:LampFlowchart.png Original artist: svg by Booyabazooka
File:Office-book.svg Source: http://upload.wikimedia.org/wikipedia/commons/a/a8/Office-book.svg License: Public domain Contributors: This and myself. Original artist: Chris Down/Tango project
File:Question_book-new.svg Source: http://upload.wikimedia.org/wikipedia/en/9/99/Question_book-new.svg License: Cc-by-sa-3.0
Contributors:
Created from scratch in Adobe Illustrator. Based on Image:Question book.png created by User:Equazcion Original artist:
Tkgd2007
File:Text_document_with_red_question_mark.svg Source: http://upload.wikimedia.org/wikipedia/commons/a/a4/Text_document_
with_red_question_mark.svg License: Public domain Contributors: Created by bdesham with Inkscape; based upon Text-x-generic.svg
from the Tango project. Original artist: Benjamin D. Esham (bdesham)
File:Wiki_letter_w_cropped.svg Source: http://upload.wikimedia.org/wikipedia/commons/1/1c/Wiki_letter_w_cropped.svg License:
CC-BY-SA-3.0 Contributors:
Wiki_letter_w.svg Original artist: Wiki_letter_w.svg: Jarkko Piiroinen
File:Wikibooks-logo-en-noslogan.svg Source: http://upload.wikimedia.org/wikipedia/commons/d/df/Wikibooks-logo-en-noslogan.
svg License: CC BY-SA 3.0 Contributors: Own work Original artist: User:Bastique, User:Ramac et al.
File:Wikibooks-logo.svg Source: http://upload.wikimedia.org/wikipedia/commons/f/fa/Wikibooks-logo.svg License: CC BY-SA 3.0
Contributors: Own work Original artist: User:Bastique, User:Ramac et al.
File:Wikiquote-logo.svg Source: http://upload.wikimedia.org/wikipedia/commons/f/fa/Wikiquote-logo.svg License: Public domain
Contributors: ? Original artist: ?
40