381

Paul Erdős talked about the "Book" where God keeps the most elegant proof of each mathematical theorem. This even inspired a book (which I believe is now in its 4th edition): Proofs from the Book.

If God had a similar book for algorithms, what algorithm(s) do you think would be a candidate(s)?

If possible, please also supply a clickable reference and the key insight(s) which make it work.

Only one algorithm per answer, please.

Martin Berger
  • 11,420
  • 3
  • 39
  • 71
Aryabhata
  • 1,855
  • 3
  • 21
  • 29

92 Answers92

124

Union-find is a beautiful problem whose best algorithm/datastructure (Disjoint Set Forest) is based on a spaghetti stack. While very simple and intuitive enough to explain to an intelligent child, it took several years to get a tight bound on its runtime. Ultimately, its behavior was discovered to be related to the inverse Ackermann Function, a function whose discovery marked a shift in perspective about computation (and was in fact included in Hilbert's On the Infinite).

Wikipedia provides a good introduction to Disjoint Set Forests.

Ryan Tenney
  • 101
  • 2
Ross Snider
  • 2,035
  • 2
  • 20
  • 33
116

Knuth-Morris-Pratt string matching. The slickest eight lines of code you'll ever see.

Jukka Suomela
  • 11,500
  • 2
  • 53
  • 116
Jeffε
  • 23,129
  • 10
  • 96
  • 163
  • 4
    It's kinda mind boggling to realize that that was something that wasn't obvious at some time and is only obvious now because they came up with it and we learnt it... I think we should apply Carr's theory of history to Mathematics and Computer Science. – Ritwik Bose Sep 02 '10 at 12:50
  • 1
    By the description, I'd say this is related to the Boyer-Moore fast substring search. – bart Sep 22 '10 at 07:20
  • 3
    @Mechko The fact that this algorithm was discovered simultaneously and independently by separate people is an indication that it is obvious to an extent. Whether something is "obvious" is a function of project constraints and broader programming environment. If you need (1) fast text searching and (2) you're aware of the importance of truly O(n) algorithms, and (3) you've encountered text with partial matches before, and (4) you have the time to do things "right", then this algorithm is probably obvious. – Matt Gallagher Jun 17 '13 at 01:20
  • In an interview Knuth said that the idea for the algorithm came from studying Stephen Cook's Two-way finite automaton for palindromes. – Kaveh Sep 04 '14 at 05:23
  • @Kaveh Please read Section 7 (Historical Remarks) from the original KMP paper. It has great remarks. About Morris writing a text editor which "was too complicated for other implementors of the system to understand". About Knuth "the first time in Knuth’s experience that automata theory had taught him how to solve a real programming problem better than he could solve it before". And " Knuth was chagrined to learn that Morris had already discovered the algorithm, without knowing Cook’s theorem;". FUN. – Hendrik Jan Oct 15 '14 at 01:07
99

The algorithm of Blum, Floyd, Pratt, Rivest, and Tarjan to find the kth element of an unsorted list in linear time is a beautiful algorithm, and only works because the numbers are just right to fit in the Master Theorem. It goes as follows:

  1. Sort each sequence of five elements.
  2. Pick out the median in each.
  3. Recur to find the median of this list.
  4. Pivot on the median of medians (as in Quicksort)
  5. Select the proper side of the list and position in that list, and recur.
Chris Pacejo
  • 101
  • 3
Derrick Stolee
  • 2,044
  • 1
  • 21
  • 34
  • 3
    This is one of my favorite algorithms. I like an intuition for it that I learnt from Chazelle's discrepancy book: the set of medians of groups of $1/\epsilon$ elements is like an $\epsilon$-net for intervals in the ordered list of the input numbers. So the algorithm follows a general paradigm: compute an $\epsilon$-net fast, solve the problem on the net, recurse on some part of the input to refine the solution, until you have the exact solution. it's very useful technique – Sasho Nikolov Mar 30 '12 at 22:34
  • 5
    BTW once you parametrize the size of the groups, the constants are not so magical. they are of course optimized to give the right thing in the Master theorem – Sasho Nikolov Mar 30 '12 at 22:36
  • Ruby implementation, https://gist.github.com/chadbrewbaker/7202412 Is there a version of the algorithm that uses (constant,log) space, or do you have to use linear scratch space to hold the medians? – Chad Brewbaker Nov 23 '13 at 15:37
  • 3
    The claim that "this only works because the numbers are just right to fit in the master theorem" is not really true. If you replace the number $5$ with a larger number $n$, it is easy to see that the two numbers that have to sum to less than $1$ converge to $3/4$ and $0$, so all sufficiently large $n$ work. $5$ is just the first number that works, it's not the only one. – Will Sawin Mar 16 '15 at 17:08
95

Binary Search is the most simple, beautiful, and useful algorithm I have ever run into.

michalmocny
  • 101
  • 1
  • 4
  • I would replace elegant with intuitive. There is nothing that elegant about it; its simplicity is its real beauty. – Robert Massaioli Sep 21 '10 at 02:48
  • @Robert Massaili: I replaced elegant with beautiful. You were right about that. – michalmocny Dec 13 '10 at 21:41
  • 4
  • In my first graduate algorithms course we had 15 minute quizzes where we had to solve 2-3 problems by hand. The first such quiz included a binary search tree and two questions about heaps. I was embarrassed and dismayed to learn I had gotten the binary search problem wrong, before being told that in a class of about 30 people there were two correct answers. But even knowing that, the fact that it took 15 years for the professional community to get right is staggering. – Stella Biderman Oct 20 '17 at 12:45
  • @jade the link is broken. Here is an archive – Benjamin Wang Aug 14 '23 at 20:19
  • OK, prepare for heresy. Classic binary search, that you linked to, is one of the most awful algorithms that our field has the misfortune of cherishing. The biggest problem is that it's almost beautiful, but most people aren't aware of the wart. Don't have to believe me, a nobody: read From Mathematics to Generic Programming by Alex Stepanov. The principle that it is based on, the bisection method, is beautiful. I can expand on this and explain in another comment if people are interested. – Jeremy W. Murphy Sep 09 '23 at 04:54
  • 1
    Essentially, there are two warts: i) stopping immediately when the value is found, in a sequence with duplicates, you don't know which one you found or how many there are; ii) returning null when it's not found throws away the work done in finding that position, which is still useful in some applications such as finding where to insert that value or searching on a prefix of a value (e.g. search for "str" to find the first word starting with it). So I'm sorry, but Binary Search, the classic definition in Knuth, is not beautiful. The beautiful variation is called equal_range. – Jeremy W. Murphy Sep 23 '23 at 04:10
89

I'm surprised not to see the Floyd-Warshall algorithm for all-pairs shortest paths here:

d[]: 2D array. d[i,j] is the cost of edge ij, or inf if there is no such edge.

for k from 1 to n:
  for i from 1 to n:
    for j from 1 to n:
      d[i,j] = min(d[i,j], d[i,k] + d[k,j])

One of the shortest, clearest non-trivial algorithms going, and $O(n^3)$ performance is very snappy when you consider that there could be $O(n^2)$ edges. That would be my poster child for dynamic programming!

user651
  • 101
  • 1
  • 3
  • 2
    This algorithm can be also generalised in a really neat way. See e.g. http://r6.ca/blog/20110808T035622Z.html and http://www.cl.cam.ac.uk/~sd601/papers/semirings.pdf – Mikhail Glushenkov Nov 25 '13 at 00:31
  • 1
    And a striking fact is that we still don’t have (polynomially) faster algorithm for APSP than Floyd’s! – Lwins Nov 01 '19 at 21:48
85

Euclidean algorithm to compute the greatest common divisor (GCD)

Deyaa
  • 544
  • 7
  • 14
75

Might seem somewhat trivial (especially in comparison with the other answers), but I think that Quicksort is really elegant. I remember that when I first saw it I thought it was really complicated, but now it seems all too simple.

Tomer Vromen
  • 623
  • 7
  • 10
  • 11
    Quicksort also raises interesting questions about what exactly the essence of an algorithm is. E.g. the standard elegant Haskell implementation looks exactly like the standard pseudo-code definition, but it has different asymptotic complexity. So, is Quicksort just about divide-and-conquer or is the clever in-situ pointer-fiddling an essential part of Quicksort? Can Quicksort even be implemented in a purely functional setting or does it require mutability? – Jörg W Mittag Sep 03 '10 at 22:28
  • 2
    The idea of the "essence" or the "moral" of an algorithm comes of course from the beautiful paper The Genuine Sieve of Eratosthenes by Melissa E. O'Neill (http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf) and the quicksort discussion comes from the LtU discussion of that paper (http://lambda-the-ultimate.org/node/3127/), specifically starting at this comment: http://lambda-the-ultimate.org/node/3127/#comment-45549 – Jörg W Mittag Sep 05 '10 at 18:32
  • 8
    @Jörg: Implementing quicksort on linked lists is completely sensible, and has the same asymptotic running time as its in-place implementation on arrays (heck, even the naive out-of-place implementation on arrays has the same running time) – both on average and in the worst case. As for space usage, this is indeed different but it must be said that even the “in-place” version requires non-constant extra space (call stack!), a fact readily overlooked. – Konrad Rudolph Sep 08 '10 at 11:31
  • Also it's worth to mention Vladimir Yaroslavskiy's Dual-Pivot Quicksort. That should be at least 20% faster original quicksort http://permalink.gmane.org/gmane.comp.java.openjdk.core-libs.devel/2628 – SaveTheRbtz Jan 31 '11 at 23:31
  • Quicksort in theory is simple (can be outlined in 4 steps) and could be highly optimized, but in practice it's very difficult to code correctly. Which is why it doesn't get my vote. – Dennis Jun 16 '13 at 13:48
  • @Konrad: Running time cannot have a lower bound than storage used, because you need to touch all the storage you use. Even if compare runtime initially dwarfs storage access, at large numbers, n-squared storage use means you have n-squared runtime. Quicksort, to be average n log n, requires in-place mutatability in the actual runtime. – Jon Watte Jun 16 '13 at 16:37
  • @Jon Agreed with the first part of the comment but (functional) quicksort does not have quadratic storage – at least I don’t see why. – Konrad Rudolph Jun 16 '13 at 20:18
63

Huffman coding for data compression.

Gary
  • 101
  • 1
  • 3
55

Polynomial identity testing with the Schwartz-Zippel lemma:

If someone woke you up in the middle of the night and asked you to test two univariate polynomial expressions for identity, you'd probably reduce them to sum-of-products normal form and compare for structural identity. Unfortunately, the reduction can take exponential time; it's analogous to reducing Boolean expressions to disjunctive normal form.

Assuming you are the sort who likes randomized algorithms, your next attempt would probably be to evaluate the polynomials at randomly chosen points in search of counterexamples, declaring the polynomials very likely to be identical if they pass enough tests. The Schwartz-Zippel lemma shows that as the number of points grows, the chance of a false positive diminishes very rapidly.

No deterministic algorithm for the problem is known that runs in polynomial time.

Per Vognsen
  • 2,161
  • 16
  • 25
  • This should have been suggested long ago! Thanks! – arnab Sep 23 '10 at 03:56
  • 1
    There are several other randomized algorithms that deserve a prominent place in the Book. For these the contrast between the deterministic and probabilistic alternatives is less striking: a deterministic algorithm usually exists but is much more complicated. – Per Vognsen Sep 23 '10 at 04:21
  • I independently invented the same algorithm while I was working on a paper a couple years ago until someone asked me isn't it Schwartz-Zippel lemma? And I said, what is that? :) – Helium Dec 03 '15 at 07:28
54

The Miller-Rabin primality test (and similar tests) should be in The Book. The idea is to take advantage of properties of primes (ie using Fermat's little theorem) to probabilistically look for a witness to the number not being prime. If no witness is found after enough random tests, the number is classified as prime.

On that note, the AKS primality test that showed PRIMES is in P should certainly be in The Book!

Lev Reyzin
  • 11,968
  • 13
  • 63
  • 103
48

Depth First Search. It is the basis of many other algorithms. It is also deceivingly simple: For example, if you replace the queue in a BFS implementation by a stack, do you get DFS?

Radu GRIGore
  • 4,796
  • 30
  • 69
  • 1
    It is also the basis of Prolog execution! – muad Aug 19 '10 at 07:14
  • 1
    What's the point about BFS with a stack I'm missing? I would have thought that the answer is "yes, you get DFS". – Omar Antolín-Camarena Jun 16 '13 at 13:28
  • 3
    Well, everybody seems to think this problem is trivial. Also, everybody seems to think the answer is "yes", which is wrong. The answer is actually "depends on which BFS implementation you start with". See http://cs.stackexchange.com/questions/329/do-you-get-dfs-if-you-change-the-queue-to-a-stack-in-a-bfs-implementation (This is a question I posted to help with the beta phase of CS.SE) – Radu GRIGore Jun 23 '13 at 10:11
  • It's also briefly discussed here: http://www.ics.uci.edu//~eppstein/161/960215.html – Radu GRIGore Jun 23 '13 at 10:16
45

Dijkstra's algorithm: the single-source shortest path problem for a graph with nonnegative edge path costs. It's used everywhere, and is one of the most beautiful algorithms out there. The internet couldn't be routed without it - it is a core part of routing protocols IS-IS and OSPF (Open Shortest Path First).

  1. Assign to every node a distance value. Set it to zero for our initial node and to infinity for all other nodes.
  2. Mark all nodes as unvisited. Set initial node as current.
  3. For current node, consider all its unvisited neighbors and calculate their tentative distance (from the initial node). For example, if current node (A) has distance of 6, and an edge connecting it with another node (B) is 2, the distance to B through A will be 6+2=8. If this distance is less than the previously recorded distance (infinity in the beginning, zero for the initial node), overwrite the distance.
  4. When we are done considering all neighbors of the current node, mark it as visited. A visited node will not be checked ever again; its distance recorded now is final and minimal.
  5. If all nodes have been visited, finish. Otherwise, set the unvisited node with the smallest distance (from the initial node) as the next "current node" and continue from step 3.
45

The Sieve of Eratosthenes, simple & intuitive.

I also like the beauty of Horner's Algorithm.

Ryan Tenney
  • 101
  • 2
44

Gentry's Fully Homomorphic Encryption Scheme (either over ideal lattices or over the integers) is terribly beautiful. It allows a third party to perform arbitrary computations on encrypted data without access to a private key.

The encryption scheme is due to several keen observations.

  • To get a fully homomorphic encryption scheme, one needs only to have a scheme that is homomorphic over addition and multiplication. This is because addition and multiplication (mod 2) are enough to get AND, OR and NOT gates (and therefore Turing Completeness).
  • That if such a scheme were to be had, but due to some limitations could only be executed for circuits of some finite depth, then one can homomorphically evaluate the decryption and reencyption procedure to reset the circuit depth limitation without sacrificing key privacy.
  • That by "squashing" the depth of the circuit version of the decryption function for the scheme, one might enable a scheme originally limited to finite, shallow circuits an arbitrary number of computations.

In his thesis, Craig Gentry solved a long standing (and gorgeous) open problem in cryptography. The fact that a fully homomorphic scheme does exist demands that we recognize that there is some inherent structure to computability that we may have otherwise ignored.

http://crypto.stanford.edu/craig/craig-thesis.pdf

http://eprint.iacr.org/2009/616.pdf

http://portal.acm.org/citation.cfm?id=1666420.1666445

Ross Snider
  • 2,035
  • 2
  • 20
  • 33
43

The Cooley-Tukey FFT Algorithm.

andand
  • 101
  • 1
  • 4
40

Strassen's algorithm for matrix multiplication.

Kaveh
  • 21,577
  • 8
  • 82
  • 183
Noam
  • 9,369
  • 47
  • 58
36

The Gale-Shapley stable marriage algorithm. This algorithm is greedy and very simple, it isn't obvious at first why it would work, but then the proof of correctness is again easy to understand.

34

The linear time algorithm for constructing suffix arrays is truly beautiful, although it didn't really receive the recognition it deserved http://www.cs.helsinki.fi/u/tpkarkka/publications/icalp03.pdf

zotachidil
  • 622
  • 7
  • 14
  • I do think that it has received the recognition it deserves – what makes you think otherwise? For example, it’s implemented in the C++ sequence analysis library SeqAn. – Konrad Rudolph Sep 08 '10 at 11:11
  • It is worth mentioning that there are now a number of other linear and non linear time suffix array construction algorithms which, although nowhere near as pretty, may be quite a lot faster in practice. "An efficient, versatile approach to suffix sorting", Journal of Experimental Algorithmics (JEA), Volume 12, June 2008 has some experimental results along these lines. – Simd Jun 02 '11 at 19:35
  • @Raphael: I'm a bit wary of the fact that on p. 3 of that JEA paper, they give only what they "believe" is a "loose" bound of O(n^2 log n)... Do you know any papers with provably linear-time algorithms that are faster in practice than the Skew Algorithm? – user651 Sep 22 '11 at 08:58
33

The Tortoise and hare Algorithm. I like it because I'm sure that even if I wasted my entire life trying to find it, there is no way I would come up with such an Idea.

Tobias Neukom
  • 101
  • 1
  • 2
  • 6
    Do you know the dumb algorithm that solves the problem with the same asymptotics and follows an algorithmic design pattern? I'm talking about iterative deepening. In the nth iteration you start at the 2^n-th successor of the root and look 2^n successors forward in search of a recurrence. Even though you're retracing some of your steps with every iteration, the geometric growth rate of the search radius means that it doesn't affect the asymptotics. – Per Vognsen Sep 23 '10 at 15:22
33

I was impressed when I first saw the algorithm for reservoir sampling and its proof. It is the typical "brain teaser" type puzzle with an extremely simple solution. I think it definitely belongs to the book, both the one for algorithms as well as for mathematical theorems.

As for the book, the story goes that when Erdös died and went to heaven, he requested to meet with God. The request was granted and for the meeting Erdös had only one question. "May I look in the book?" God said yes and led Erdös to it. Naturally very excited, Erdös opens the book only to see the following.

Theorem 1: ...
Proof: Obvious.

Theorem 2: ...
Proof: Obvious.

Theorem 3: ...
Proof: Obvious.

32

Merge Sort. Simple, elegant, efficient.

Giorgio Camerani
  • 6,842
  • 1
  • 34
  • 64
32

An example as fundamental and "trivial" as Euclid's proof of infinitely many primes:

2-approximation for MAX-CUT -- Independently for each vertex, assign it to one of the two partitions with equal probability.

Jukka Suomela
  • 11,500
  • 2
  • 53
  • 116
arnab
  • 7,000
  • 1
  • 38
  • 55
  • 8
    Yes, a very nice algorithm. Less trivially, at the cost of another factor of 2, this algorithm also works for maximizing any submodular function, not just the graph cut function. This is a result of Feige, Mirrokni, and Vondrak from FOCS 07 – Aaron Roth Aug 17 '10 at 20:23
32

Gaussian elimination. It completes the generalization sequence from the Euclidean GCD algorithm to Knuth-Bendix.

Mitch
  • 905
  • 8
  • 19
  • 1
    BTW, what's the generalization sequence, and where does Buchberger's algorithm for Grobner basis fit into it? (It seems analogous to Knuth-Bendix, but I've seen a mention somewhere that it sort of generalizes Gaussian elimination…) – ShreevatsaR Aug 30 '10 at 00:03
  • 7
    the sequence is: Euclidean GCD -> Gaussian Elimination -> Buchberger -> Knuth-Bendix. One can also put in (instead of Gaussian Elimination) univariate polynomial division and modulo (in the generalization order it is 'apart' from Gaussian Elimination, GE is multivariate degree 1, polynomial ring is univariate unlimited degree, Buchberger's is multivariate unlimited degree. The generalization jump is largest from EGCD to GE or polynomial ring because of the addition of variables, and then also large from Buchberger to KB because of the unlimited signature. – Mitch Aug 30 '10 at 15:59
  • +1: Euclidean algorithm solves the most celebrated equation ax-by=1 in math. Why it doesn't show up in CS more often is a mystery. – Tegiri Nenashi Feb 16 '11 at 21:36
31

I've always been partial to Christofides' Algorithm that gives a (3/2)-approximation for metric TSP. In fact, call me easy to please, but I even liked the 2-approximation algorithm that came before it. Christofides' trick of making a minimum weight spanning tree Eulerian by adding a matching of its odd-degree vertices (instead of duplicating all edges) is simple and elegant, and it takes little to convince one that this matching has no more than half the weight of an optimum tour.

Jukka Suomela
  • 11,500
  • 2
  • 53
  • 116
James King
  • 2,613
  • 18
  • 25
27

How about Grover's algorithm? It's one of the simplest quantum algorithms, and allows you to search an unsorted database in $O(\sqrt N)$. It is provably optimal, and also provably outperforms any classical algorithm. For a bonus it is very easy to understand and intuitive.

Jukka Suomela
  • 11,500
  • 2
  • 53
  • 116
Joe Fitzsimons
  • 13,675
  • 47
  • 91
26

Algorithms for linear programming: Simplex, Ellipsoid, and interior point methods.

http://en.wikipedia.org/wiki/Linear_programming#Algorithms

Jukka Suomela
  • 11,500
  • 2
  • 53
  • 116
Kaveh
  • 21,577
  • 8
  • 82
  • 183
  • And indeed, several Nobel prizes were given for advancing our understanding of these problems. – Ross Snider Aug 18 '10 at 00:14
  • @Ross Kantorovich won the Nobel prize in Economics for inventing LP and applying it to resource allocations. What other prizes were you thinking of? – Mark Reitblatt Nov 16 '10 at 02:00
  • @Mark Koopermans was awarded the nobel prize with Kantorovich, but it was still inaccurate of me to say "several." – Ross Snider Nov 16 '10 at 09:57
22

Marcus Hutter's The Fastest and Shortest Algorithm for All Well-Defined Problems.

This kind of goes against the spirit of the other offerings in this list, since it is only of theoretical and not practical interest, but then again the title kind of says it all. Perhaps it should be included as a cautionary tale for those who would look only at the asymptotic behavior of an algorithm.

Kurt
  • 839
  • 10
  • 13
22

Knuth's Algorithm X finds all solutions to the exact cover problem. What is so magical about it is the technique he proposed to efficiently implement it: Dancing Links.

didest
  • 1,551
  • 16
  • 25
22

Robin Moser algorithm for solving a certain class of SAT instances. Such instances are solvable by Lovasz Local Lemma. Moser algorithm is indeed a de-randomization of the statement of the lemma.

I think that is some years his algorithm (and the technique for its correctness proof) will be well digested and refined to the point of being a viable candidate for an Algorithm from the Book.

This version is an extension of his original paper, written with Gábor Tardos.

MassimoLauria
  • 1,841
  • 16
  • 21
21

I think we must include Schieber-Vishkin's, which answers lowest common ancestor queries in constant time, preprocessing the forest in linear time.

I like Knuth's exposition in Volume 4 Fascicle 1, and his musing. He said it took him two entire days to fully understand it, and I remember his words:

I think it's quite beautiful, but amazingly it's got a bad press in the literature (..) It's based on mathematics that excites me.

Jukka Suomela
  • 11,500
  • 2
  • 53
  • 116
didest
  • 1,551
  • 16
  • 25
20

Expander codes

Gallager showed in the 1960's that random low density parity codes have good rate and relative distance with high probability. But it was Sipser and Spielman (1994), following work of Tanner (1981), who had the beautiful insight that it is the expansion of the natural bipartite graph associated with the parity check matrix of the code that leads to the code being good. They then proved that the following simple decoding algorithm runs in linear time for any expander code: repeatedly check if there exists a bit of the received word which violates more than half of the parity checks it is involved in, and if there is such a bit, flip it.

Two footnotes:

  1. Graphs of such expansion were not explicitly constructible at the time of Spielman and Sipser, but they now are due to work of Capalbo, Reingold, Vadhan and Wigderson (2002). Sipser and Spielman themselves constructed linear time decodable codes by using the Tanner product construction.

  2. Spielman (1995) developed these ideas further to give a code with both linear time encoding and decoding.

arnab
  • 7,000
  • 1
  • 38
  • 55
18

The algorithm that amazed me the most is Timothy Chan's O(n log h) planar convex hull algorithm: http://www.cs.uwaterloo.ca/~tmchan/conv23d.ps.gz

I find it impressive how the proper application of several simple techniques led to an optimal algorithm for such a classic problem, 10 years after the first optimal algorithm for the problem.

16

Computing the closest pair of points in the plane in linear time (especially because there is Omega(n log n) lower bound in the comparison model). The algorithm is originally due to Rabin, but there are considerably simpler and more elegant versions. See for example: http://valis.cs.uiuc.edu/~sariel/teach/notes/aprx/lec/01_min_disk.pdf

Sariel Har-Peled
  • 9,626
  • 31
  • 53
15

I would add universal hashing (or more generally pairwise independent hash functions) of Carter and Wegman. While not really an algorithm in itself, it is the enabling technology in a lot of fantastic randomized algorithms. To name a few:

  • Randomized equality testing (hugely important in communication protocols)
  • Hashing with chaining
  • Count-min sketches
Rasmus Pagh
  • 962
  • 6
  • 11
13

The Goemans-Williamson algorithm for MAX-CUT. It was one of the first SDP rounding schemes to be analyzed, and uses a simple geometric fact that seems totally unrelated to the problem at first sight.

13

This collection of answers would be a great start on an outline for a book with that title! I have really enjoyed Proofs from the Book, have even purchased all four editions.

I would include the edge-flipping algorithm for constructing the Delaunay Triangulation in 2D. Even though it is not optimal.

Joseph O'Rourke
  • 3,753
  • 23
  • 41
13

Moore's O(n) Majority voting algorithm is like a magic-trick!

Abhay
  • 1
  • 1
  • 3
12

Avi Wigderson in Part II of these lectures gives the following examples of algorithmic gems, with pseudocode:

Shortest path (Dijkstra's algorithm)

Pattern matching (Knuth-Morris-Pratt's algorithm)

Fast Fourier Transform (Cooley-Tukey's algorithm)

Error Correction (Berlekamp-Massey's algorithm)

Manu
  • 7,659
  • 3
  • 37
  • 42
  • This would be an even better answer, if you could name a concrete algorithm for these problems which you think should be called an "algorithm from the book". (FFT is a fine answer already) – Moritz Aug 17 '10 at 21:44
  • 10
    Please, one algorithm per answer. (And we already have KMP.) – Jukka Suomela Aug 17 '10 at 23:18
  • I'm pretty sure Berlekamp-Massey's algo is not error correction. To me it seems more along the lines of reverse engineering an LFSR back to a particular state given the output bits of the mentioned LFSR. I don't see that as error correction more than a well formed parsing algorithm. – Corey Ogburn Aug 24 '10 at 18:05
12

We cannot forget Binary Decision Diagrams, a family of data structures that have become the method for representing boolean functions. I think the key insight is the dual nature of being a data structure and a "algorithm" at the same time (which indeed is the powerful idea behind Knuth-Morris-Pratt.)

My reference is again Knuth's Volume 4 Fascicle 1, and you can see his musings here and here.

didest
  • 1,551
  • 16
  • 25
11

Ford–Fulkerson Algorithm has to be there ... Also Sanjeev Arora's PTAS for Euclidean TSP will be there.

11

Kosaraju's Algorithm to find the strongly connected components of a directed graph. Consists essentially of doing two DFS traversals on the digraph, the second after reversing all the edges and picking vertices in the reverse order as they were seen in the first traversal.

gphilip
  • 1,394
  • 1
  • 12
  • 31
11

Lenstra-Lenstra-Lovász Lattice Basis Reduction. Maybe not quite from the book (since it's, at least to me, a bit messy), but it definitely is worth a mention here.

alpoge
  • 732
  • 6
  • 16
  • thats an awesome choice...i like the way they analyze the algorithm...by picking what, in my opinion, is a very non-trivial thing to amortize on – Akash Kumar Feb 25 '11 at 03:08
10

The (random projection algorithm implicit in the) Johnson-Lindenstrauss lemma!

Kunal
  • 304
  • 1
  • 5
10

I propose Reed-Solomon coding. The basic idea is that you can encode your data as a polynomial over a finite field. You can then evaluate this polynomial at several different points and these values become the messages that you will send. If the degree of the polynomial is N, then a receiving party only needs to receive N+1 messages in order to reconstruct the polynomial and hence the original data.

I find this extremely elegant. I just wish I had more cause to use it.

dan_waterworth
  • 176
  • 1
  • 5
10

Floyd's Cycle Finding Algorithm is one of the most beautiful things I've seen. Especially the part where he finds where the cycle begins.

http://en.wikipedia.org/wiki/Cycle_detection

Ritwik Bose
  • 181
  • 1
  • 7
9

The O(n) algorithm for finding the maximum-sum contiguous subarray of a list of integers L.

  • L can contain both positive and negative integers
  • L is not necessarily sorted
  • L can contain duplicate entries
  • subarray length can be in the range [1, n] where n is the length of L

For example the list {-1, 500, -100, 101} has a maximum-sum subsequence of {500, -100, 101}.

I learned about this algorithm from Jon Bentley's Programming Pearls. Note the code contains a few versions of this algorithm... the last version is O(n).

whoisit
  • 125
  • 5
MrDatabase
  • 131
  • 5
9

The Risch algorithm finds a nice, elementary form of integrals or tells you that it doesn't exist. Solves a problem open since Newton/Leibniz invented calculus and is so complicated that the full version has never been implemented.

In particular, it tells you why $e^{x^2}$, $x^x$, $\frac{log x}{x}$ and the like don't have elementary primitives, and gives you a way of constructing the primitive if your function admits one.

http://en.wikipedia.org/wiki/Risch_algorithm

nimish
  • 133
  • 6
  • That seems to be an incredibly complicated algorithm. According to Wikipedia, no software currently implements the full algorithm due to its complexity. In fact, it's not even a terminating algorithm. Other than the problem it solves, in what sense is this an "elegant" algorithm? – Mark Reitblatt Nov 16 '10 at 00:20
9

I think that there should be at least one persistant data structure. In particular, the "persistant array" let us obtains a lot of other persistant data-structures where we wouldn't expect them.

Arthur MILCHIOR
  • 1,561
  • 10
  • 19
9

I guess the algorithm to "hash-cons" is really interesting. This idea let us usually save both memory, time, and avoid doing many time the same computation by finding quickly equality between many structures in memory, or that has been in memory (at least that has been in memory and did not need to be garbage collected).

Arthur MILCHIOR
  • 1,561
  • 10
  • 19
9

The Simplex Algorithm is an algorithm for solving linear programming problems. While it has an exponential worst case running time it is very fast in practice. There are polynomial running time algorithms, but none are as simple to implement as the simplex algorithm. The algorithm works by traversing the edges of a simplex and it's possible that you will have to traverse every edge, which is where the exponential bound comes from.

8

An algorithm that I find truly simple and elegant is the Rabin-Karp algorithm of using rolling-hashes for linear time string search. A lot simpler to wrap your head around than KMP.

MAK
  • 101
  • 3
8

Everyone says Knuth-Morris-Pratt. I don't think the Boyer-Moore string-matching algorithm gets enough credit.

There's a wonderful exploration Boyer-Moore's implementation in grep on ridiculousfish. For the more academically-inclined, Mike Haertel, grep's longtime maintainer, explains why grep is so fast.

apc
  • 181
  • 2
8

I looked through all the answers and it seems that many of them are not describing Algorithms from the Book. Some are extremely useful, but not particularly beautiful, in my opinion. It's hard to say what makes an algorithm beautiful, but I will try to argue that quicksort would not be found in The Book. It's a fairly simple algorithm, which makes it a good candidate for The Book, but there is one major issue:

The behaviour of quicksort is inconsistent. It performs well in practice, but bad pivot choices could lead to quadratic running-time. And the pivot choice is arbitrary. There is no way to make a good pivot choice. Since we are talking about algorithms, I think we can agree that running-time matters.

Though, there is a sorting algorithm that I would expect to find in The Book, and that is mergesort:

Each element is viewed as a sorted subsequence of size one.
Merge pairs of adjacent subsequences repeatedly.
Stop when there is only one sorted subsequence left.

The beauty of mergesort is in the simplicity of the merge function that merges two sorted subsequences into one sorted subsequence. Try to code this function, and enjoy.

ara
  • 1
  • 1
  • I disagree that "There is no way to make a good pivot choice." There may be no instant way to make a good pivot choice, but median of medians will find a good pivot. – jbapple Sep 22 '10 at 21:03
  • 1
    I think the point really is that in terms of simplicity, elegance, and computational economy, Mergesort belongs in the Book and Quicksort probably does not. I don't completely agree, but +1 for bringing up the idea that the Book isn't just a collection of favorite algorithms. – whuber Oct 01 '10 at 20:20
  • 4
    The most elegant way to choose the quicksort pivot is to choose it randomly. Then (and only then) quicksort belongs in The Book. – Jeffε Apr 01 '12 at 16:03
  • Choosing a pivot randomly is a deus ex machina non-answer. We're talking about The Book here, not The Book plus a qualified source of randomness. Mergesort in, quicksort out. – Daniel Lyons Jun 17 '13 at 03:28
8

I wonder nobody mentioned Schöning's random-walk algorithm for 3-SAT solving yet. It it very simple:

  • Start with a random assignment
  • As long as there exists an unsatisfied clause: Flip a randomly-selected variable in this clause

Nevertheless, it is to date one of the fastest algorithms in its class.

8

The Viterbi algorithm, low-density parity-check codes, and turbo codes- communication at the noise floor!

johne
  • 227
  • 2
  • 7
8

I'm not sure if the question requests particularly beautiful algorithms, but as far as useful and simple algorithms go..

I propose steepest descent. By this I specifically mean an iterative minimization technique for a function $f$ over a domain with norm $\|\cdot\|$ which, at every step, from an iterate $x$, performs linesearch in the direction(*) $v := \textrm{argmin}_u \{\nabla f(x)^T u : \|u\| = 1\}$. (For two texts which use this terminology and provide discussion, see Boyd/Vandenberghe or Hiriart-Urruty/Lemarechal.)

When $\|\cdot\|$ is the $l_2$ norm, this gives gradient descent, which was certainly known to Cauchy but arguably known by every living organism. When $\|\cdot\|$ is the $l_1$ norm, this is greedy coordinate ascent, which includes boosting, which is similar to Gauss-Seidel iterations.

When $\|\cdot\|$ is any norm over $\mathbb{R}^n$ and $f$ is strongly convex, this method exhibits linear convergence (i.e. $\mathcal{O}(\ln(1/\epsilon))$ iterations to error $\epsilon$); for a proof of this, see Boyd/Vandenberghe. (The constants are bad because it uses the ones provided by norm equivalence.)

Certainly, there are methods with faster convergence, the ability to handle nonsmooth objectives, etc. But this method is simple and can work decently, and thus is in widespread use, and always will be.

(*) There may be more than one minimizer (consider $l_1$ norm), but there is always at least one (gradients are linear, and the set is compact).

matus
  • 2,096
  • 14
  • 14
  • note that "Newtons method" for finding solutions via the derivative is a 1-d analogue of multivariate steepest descent. – vzn Jan 25 '12 at 23:08
7

How can we forget Shor's quantum factoring algorithm ? Even though there may never be a universal quantum computer capable of demonstrating the ability of the algorithm to factor really large integers, it is still a stroke of genius to even think of such an algorithm in the first place.

William Hird
  • 1
  • 1
  • 2
7

The 2-approximation algorithm for Knapsack:

First, consider the trivial algorithm: select the highest value item that fits. This can obviously be arbitrarily far from optimal.

Now consider the greedy algorithm: greedily select the highest value density items. This can also be arbitrarily far from optimal.

Now, the 2-approximation algorithm: Run Trivial and Greedy. Take whichever solution has the highest value. This is guaranteed to be within a factor of 2 of optimal.

Mark Reitblatt
  • 1,690
  • 15
  • 20
7

I think that LR parsers are beautiful. A language is deterministic context-free if and only if there exists a LR(1) grammar for it.

didest
  • 1,551
  • 16
  • 25
7

Knuth-Bendix algorithm and the analogous Buchberger's algorithm.

didest
  • 1,551
  • 16
  • 25
7

I would like to put some non-deterministic algorithm, which may also be in the Book.

In particular, I think of the Immerman's algorithm for non-reachability in directed graph in non deterministic log space ! (or equivalently reachability in universal logspace).

And also probably the algorithm to reduce any problem in NP into an NP-complete problem like SAT; because it is really impressive that one algorithm like this exists !

Arthur MILCHIOR
  • 1,561
  • 10
  • 19
7

The (exponential time) algorithms for generating all combinations or all permutations of a given set, list, or structure. They can usually be expressed both concisely and beautifully, and optimizations in this combinatorial generation are often equivalent to some of the most celebrated algorithms. For example: A* search instead of unordered search, when applied to the "generate all paths from X and find the shortest ones" problem, exactly yields Dijkstra's Algorithm!

I simply love that the following is actually an algorithm that will work:

def solve(problem):
    foreach answer in generate_all_possible_answers(problem): 
        if is_good_enough(answer, problem): 
            return answer
    return "No answer found"
Peter Boothe
  • 1,791
  • 13
  • 17
7

An algorithm I consider to be very nice and simple is the classic fixed parameterized algorithm for vertex covers of size at most $k$. It runs in time $2^k n^c$ for some constant $c>0$.

It is based on the simple observation that either a vertex is in the cover or all its neighbors must be. Thus the following pseudo-code applies:

G: a graph with n vertices
k: the maximum size of the cover

def Vertex_Cover(G,k): 
    if k<=0 and |E(G)|!=0: return False
    else:
         N= the set of neighbors of an arbitrary vertex v
         H1= G - {v}
         H2= G - N  
         return Vertex_Cover(H1,k-1) or Vetex_Cover(H2,k-|N|) 

Of course such procedure can be implemented in a decision tree fashion.

MassimoLauria
  • 1,841
  • 16
  • 21
  • Oh yes, I absolutely love this algorithm! And there is an even more preliminary version of it (same running time, though) which branches on edges. Pick an edge $(u,v)$. Since it must be covered, at least one of $u$ or $v$ must belong to any vertex cover; and we branch on both possibilities. Thank you for suggesting this, I was just about to! :) – Neeldhara Sep 04 '10 at 20:13
6

Do you know bucket sort?

In my opinion, it is the most elegant, simply & yet it is an incredibly powerfull sorting algorithm

6

I think that the process of finding a diagonal proof is an algorithm.

The idea of if you can generate a matrix for various things and then if you can find some answer that differs on the diagonal you have a reductio ad absurdam.

I find them sublime.... and beautiful. I somehow feel when you are at the moment of grasping, for example, the diagonal for the proof of the uncountability of the real,.. its always for me like you are peering through reality into the great mystery of it all.

alt text

image sourced from this wikipedia article

Ilan
  • 101
  • 1
  • 2
6

I would add reservoir sampling and the Knuth-Fisher-Yates shuffle. Especially when you start to see the connection between the 2 algorithms.

didest
  • 1,551
  • 16
  • 25
5

Boyer-Moore string matching.

I remember when our lecturer taught us about it. He said: "And here comes an algorithm which is impossible to understand completely...". He was right, I still don't fully understand why and how it works, but I nevertheless believe it's an elegant algorithm.

Martin
  • 309
  • 3
  • 5
5

Savitch's Algorithm: a simple recursive algorithm for the Reachability problem, with a conceptually deep consequence: PSPACE=NPSPACE.

Vincenzo
  • 751
  • 6
  • 11
4

The question:

Given an array [a1 a2 ... an b1 b2 ...bn] of 2n elements. Give an in-place algorithm to convert that array to [b1 a1 b2 a2 ... bn an].

I like the linear time solution for this here: http://arxiv.org/abs/0805.1598

4

If Dijkstra is specified, I think that Bellman-Ford is even a better candidate.

rursw1
  • 386
  • 4
  • 8
4

Zeilberger's algorithm, which extends Gosper's algorithm for finding closed-forms of binomial sums.

Knuth included an exercise in TAoCP "[50] Develop computer programs for simplifying sums that involve binomial coeficients" and thanks to Zeilberger's algorithm and related developments it can be considered solved.

Andrew
  • 284
  • 1
  • 16
4

theres a really wonderful way to describe in place quicksort

in particular:

let i,j be your initial upper and lower indices for an array a (or slice thereof) . randomly pick an integer $\ell$ in the interval [i,j] as the pivot $p=a[\ell]$. As for the the number of entries greater or equal to p, call this $m$.

We know that there are at most $\min(j-i -m+1, m)$ swap operations needed between the interval $[i, j-m]$ and the interval $[j-m+1,j]$ for us to be able to then recursively sort these two intervals. these swaps can be done by starting from indices $i$ and $j$ and scanning inward on both sides until each side has found an index that violates the ordering relative to the pivot value, at which point a swap is done, then the search continues inward, terminating at the point when these two searches meet.

edit: note that there is actually no special treatment needed for the pivot value, we just apply the swapping operation uniformly.

then recursively sort the intervals you get from the final placement of the pivot value.

this gives you the "c-style" in place quick sort, but explained in a a high level way that has very very clear correctness properties!

:)

note that this isn't a stable sort algorithm

  • +1, nice description of a nice algorithm, but I believe that technically it's not completely "in-place" because you need O(log n) (i.e. more than O(1)) stack space to store the final positions of the pivots. (Notice e.g. heapsort doesn't need this.) – user651 Aug 28 '10 at 04:59
4

Although perhaps as much a heuristic as an algorithm, since I heard about it a year or two ago, I think that the fast inverse square root is interesting. And even more intriguing that we don't know it's author or how she/he settled upon the magic number.

4

I just learned about a book entitled Algorithms unplugged, which seems relevant to this topic.

Anthony Labarre
  • 3,264
  • 1
  • 25
  • 33
4

The Ramsey-based complementation construction for Buechi automata. This is something from my advisor, that is pretty obscure, and supplanted by more recent constructions with massively better bounds. However, I really think this specific construction and the math behind it are just amazingly elegant.

If anyone is actually interested, it's section 2 introduction, 2.1, and 2.2 in the below paper, building up to Lemma 2.3.

http://www.cs.rice.edu/~vardi/papers/icalp85rj.pdf

As a fair note for anyone excited to see Ramsey there, it's a very trivial application of the infinite Ramsey theorem. However, it is also (IMO), one of the most beautiful.

Let me also put in a vote for the diagonalization proof of uncountability.

4

The Shift-And algorithm by Baeza-Yates and Gonnet (Bitap @Wikipedia) for finding all occurrences of a pattern in a text. In my opinion the simplest example of a useful seminumerical algorithm.

3

The Kalman filter, absolutely brilliant for handling data with noise: http://en.wikipedia.org/wiki/Kalman_filter

Michael
  • 101
  • 2
3

I think two algorithms that require place number notation deserve a prominent place in the book: long multiplication and division. Especially in binary these are quite elegant. Moreover, there are few algorithms that do not benefit from them.

3

In THE BOOK, there should include "The Power of Random Two Choices" paradiam.

http://www.eecs.harvard.edu/~michaelm/postscripts/handbook2001.pdf

Result is pretty simple, but super helpful to use in practical scenarios, and algorithm design . It can help to reduce computation complexity by load balance in algorithm based on "the power of random two choices"

xbob.ym
  • 181
  • 1
  • 4
3

The divide and conquer algorithm by Michael Shamos to solve the planar Closest pair of points problem in $O(n \log n)$ time. Not only is this optimal in the algebraic decision tree model of computation, it also illustrates the power of recursive thinking in a non-trivial setting.

Arindam Pal
  • 1,591
  • 12
  • 23
3

The Thompson NFA construction and, in particular, evaluation method. Probably the slickest bit of code I've ever seen.

johne
  • 227
  • 2
  • 7
3

It's such a simple thing, but in it's simplicity is it's elegance: Linear Feedback Shift Registers. As a datastructure they are simply the number of bits in the loop and at most 4 pots, in many cases only 2. With simple actions of an XOR logical equation and a shift and you have a system that goes through every possible state in a very efficient way. They're an easy to implement PRNG (psuedo random number generator) all while being easy to implement in both hardware and software.

Corey Ogburn
  • 203
  • 2
  • 7
2

I think that Hensel Lifting is pretty nifty too, and it has many applications in algorithmic number theory and algebra.

Shitikanth
  • 446
  • 4
  • 9
2

If union-find is in the book, why can't Bloom filters be there? If you are not familiar with Bloom filters, this video is a quick but nice introduction.

Helium
  • 463
  • 2
  • 12
1

Hook and shortcut from:

AN EFFICIENT PARALLEL BICONNECTIVITY ALGORITHM

Tarjan and Vishkin

http://www.umiacs.umd.edu/users/vishkin/TEACHING/ENEE759KS12/TV85.pdf

This Ruby implementation returns the partitions of a transformation where elements x,y interact with each other.

def partitions(trans)
  parent =Array.new()
  0.upto(trans.length-1) do |index|
    parent.push(index)
  end
  0.upto(trans.length-1) do |outer_index|
    0.upto(trans.length-1) do |index|
      #shortcut
      parent[index] = parent[parent[index]]
    end
    0.upto(trans.length-1) do |index|
      #hook
      if (parent[trans[index]] < parent[parent[index]])
        parent[parent[index]] = parent[trans[index]]
      end
      if (parent[index] < parent[parent[trans[index]]])
        parent[parent[trans[index]]] = parent[index]
      end
    end
  end
  return parent
end
Chad Brewbaker
  • 2,359
  • 15
  • 18
1

Polynomial time Max-Cut algorithm in planar graphs of F. HADLOCK. Hadlock gave an elegant reduction from Max-Cut to several other problems on the dual of planar graphs and finally to maximum matching problem which is polytime-solvable. I think this algorithm is very beautiful and should be included in THE BOOK.

Hung Le
  • 305
  • 1
  • 9
0

I am sure "Ancient Egyptian Multiplication" algorithm will at least find a mention in sidenote in the BOOK. Simple, elegant and has an known or most probably unknown side effect of one of the first usages of binary number. Still wondering how they figured it out in the first place.

Sai Venkat
  • 316
  • 3
  • 7
0

The algorithm that uses Pascal's Triangle (wikipedia) to find "a choose b". Especially useful when a!, b!, and/or (a - b)! is so large that the traditional expression a!/b!(a-b)! is hard to compute. For example "51 choose 23".

MrDatabase
  • 131
  • 5
0

From the world of purely functional data structures and algorithms, Gérard Huet's zipper comes to my mind.

Normally, PFDS do not expose local structure, due to the absence of explicit pointers. If you want to access a certain node in a tree, you're out of luck.

However, with an extremely simple insight (just "turn the tree inside-out" and remember the path structure from your location), accessing specific locations in PFDS is made possible, all in a purely-functional manner. This, basically, is the essence of the zipper.

If God is not a functional programmer and would only include one PFDS in the Book, it would have to be the zipper.

xrq
  • 1,175
  • 6
  • 17
0

I like the CORDIC algorithm for solving trigonometric and hyperbolic functions, especially when implemented using fixed-point integer representations.

oosterwal
  • 131
  • 2
-1

As we talk of a book of "God" and a beautiful algorithm, something that comes to my mind is Conway's Game of Life. It sets a grid as a cellular automaton and sets the following simple rules:

  1. Any live cell with fewer than two live neighbours dies, as if caused by under-population.

  2. Any live cell with two or three live neighbours lives on to the next generation.

  3. Any live cell with more than three live neighbours dies, as if by overcrowding.

  4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

Amazing, how simple rules like these and a random seeded initialization can achieve something as beautiful as life and evolution.

saikat
  • 175
  • 5
  • While Conway has made significant contributions to mathematics (surreal numbers, monstrous moonshine, free will theorem not to mention them), I am skeptical of the claims regarding the Game of Life. Is there any evidence that it allows the emergence of complex multiscale structures as witnessed in real life? See e.g. http://www.hpl.hp.com/techreports/2006/HPL-2006-2.pdf – Super0 Feb 28 '14 at 02:37
-2

I would like to make a basic remark which doesn't appear in the other answers. The elegance/beauty is somewhat subjective so I wouldn't pick it as a primary criterion for a book of algorithms. It seems more rational to consider the following criterions:

  • usefulness: does the algorithm have important applications?
  • intuitivity: is the algorithm easy to understand/implement; does it avoid complex data structures?
  • conciseness: does the algorithm have a short description in pseudo-code or natural language?

Personally, I rank these three criterions in this order, from the most to the least important. In particular, I advocate a "principle of maximum usefulness", i.e. a good algorithm is one that finds multiple uses for seemingly unrelated applications.

An example is provided by the "merge sort" algorithm: in addition to providing a fast sorting method, it also allows to compute the number of inversions of a permutation in quasi-linear time, i.e. better than the naive quadratic approach. Another example is the simple polynomial algorithm for coloring chordal graphs, which finds applications such as timetabling and register allocation.

Super0
  • 269
  • 2
  • 4
  • 1
    I think you are missing the joke. The mathematician Paul Erdős was famous for exclaiming "This one is from The Book" when he learned of a beautiful and elegant proof. He imagined that the Supreme Fascist (his term for God) greedily kept all the most beautiful proofs in The Book, but would not reveal them to mere mortals. Later this inspired a book titled "Proofs from The Book" but that is beside the point. So this question is not about writing a book of algorithms, it's about elegance and beauty. – Sasho Nikolov Feb 28 '14 at 16:46
  • I think that the quest for beauty in math is due to cultural reasons, probably because of its roots in geometry. On the other hand, algorithmics is about solving concrete problems, and thus can be pushed in two antagonistic directions: maximum efficiency versus maximum applicability. It seems clear to me that a book of algorithms, should it ever exist, must favor the second direction, possibly excluding some established algorithms that are fast but of limited use. Then again, I apologize for my bad sense of humor, but I consider this a serious question even if it seems a joke on the surface. – Super0 Feb 28 '14 at 18:33
  • 1
    the question is serious, but it asks about elegance, not "what should be in a book about algorithms" (rather it's "what algorithms are from The Book"). by the way quite a few books on algorithms exist.. – Sasho Nikolov Feb 28 '14 at 19:47