INTRODUCTION
TO ALGORITHMS
A Creative Approach
INTRODUCTION TO ALGORITHMS
A Creative
Approach
UDIMANBER
University of Arizona
\342\226\274\342\226\274
ADDISON-WESLEY PUBLISHING COMPANY
Reading,
Massachusetts
\342\200\242Menlo Park, California \342\200\242New York Don Mills,Ontario
\342\200\242Wokingham, England \342\200\242Amsterdam Bonn \342\200\242
Sydney \342\200\242
Singapore \342\200\242
Tokyo \342\200\242Madrid \342\200\242San Juan
Library of
Congress Cataloging-in-PublicationData
Manber, Udi.
Introduction to algorithms.
Includes bibliographies
and index.1. Data structures
(Computer science)
2.
Algorithms. I. Title.QA76.9.D35M36 1989
005.7 ' 3 88-2186
ISBN 0-201-12037-2
Reproduced by Addison-Wesley from
camera-ready copysupplied
by the author.The programs and
applications presented
in this book have been included for theirinstructional value. They have
been tested
with care, but are not guaranteed for anypurpose. The publisher does not offer any warranties or
representation,
nor does it acceptany liabilities with respect tothe programs or applications.
Reprinted with corrections October, 1989
Copyright \302\2511989 by Addison-Wesley Publishing
Company Inc.
All rights reserved. No part
of
this publication may be reproduced,stored
in a retrievalsystem, or transmitted, in any form or by any means, electronic, mechanical, photocopying,
recording, or
otherwise, without prior written permissionof
the publisher.Printed in the United States of America. Published simultaneously in Canada.
EFGHIJ-DO-943210
To
my parents Eva and Meshulam
PREFACE
This book grew out of my frustrations with not being able to explain algorithms
clearly.
Like
many other teachers, I discovered that not only is it hard forsome
students to solve(what seemed to
me) simple problems
by themselves, but it isalso
hard for them to understand the solutions that are given tothem. I believe
that these two parts \342\200\224the creation and the explanation \342\200\224are related and should not be separated. It isessential to follow
the steps leading to asolution in order to understand it fully. It is not sufficient tolook at the finished product.
This book emphasizes the creative side of algorithm
design. Its
main purpose is toshow the reader how to design
a
new algorithm. Algorithms are notdescribed
in asequence of '
'problem
X, algorithm A, algorithm A\\ program P, program P\\\" and so on.Instead, the sequence usually (although not
always) looks
more like \"problem X, thestraightforward algorithm, its drawbacks, the difficulties overcoming these drawbacks,
first attempts at a better algorithm (including
possible
wrong turns), improvements, analysis, relation to othermethods and
algorithms,\" and so on. Thegoal is to present
analgorithm not in a way that makes it easier for
a
programmer to translate into aprogram,
but rather in a way that makes it easier to understand the algorithm's principles. The
algorithms are thus explained through
a creative process,
rather than as finished products.Our goals
in teaching algorithms are to show not only how to solve particular problems,but also how to
solve
new problems when they arise in the future. Teaching the thinkinginvolved in designing an algorithm is
as
important as teaching the detailsof
the solution.To further help the thinking process involved in creating algorithms, an
\"old-new\" methodology for designing algorithms is used in this
book. This
methodology covers many known techniques for designing algorithms, and it also
provides an elegant intuitive framework for explaining the
design of
algorithms in moredepth. It does not, however, cover all possible ways of designing algorithms, and we
do
not use it exclusively. The heart of the methodology lies in an analogy between the
intellectual process of proving mathematical
theorems
by induction and that of designingcombinatorial
algorithms. Although these two processesserve
different purposes and achieve different typesof results,
they are more similar than they may appear tobe. This
analogy has been observed by many people.
The
novelty of this book is the degree towhich this analogy is exploited. We show that the analogy encompasses many known
algorithm-design techniques,
and helps considerably in theprocess of
algorithm creation.The methodology is
discussed
briefly in Chapter 1 and is introduced more formally in Chapter5.
vi Preface
Consider the following analogy.
Suppose
that you arrive at an unfamiliar city, renta car, and want directions to get toyour hotel. You would be quite impatient if you were
told about the history of the city, its general layout, the traffic patterns, and so
on.
Youwould rather have directions
of
the form \"go straight for two blocks, turn right, gostraight for three miles,\" and
so on.
However, your outlook would change if youplanned to live in that city for a long time. You could probably get around for a while
with directions of the second form
(if
you find someone who gives you those directions), but eventually you will need to knowmore
about the city. This book isnot a source of easydirections.
It does contain explanations of how to solve many particularproblems,
but the emphasis is on
general principles
and methods. As a result, the book ischallenging. It demands
involvement
and thinking. I believe that the extra effort is well worthwhile.The
design of
efficient nonnumeric algorithms is becoming important in many diverse fields, including mathematics, statistics, molecular biology, and engineering.This book can
serve as
an introduction to algorithms and to nonnumeric computations in general. Manyprofessionals, and even
scientists not deeply involved with computers, believe that programming is nothing more than grungy nonintellectual work. It sometimes is. But sucha belief
may lead to straightforward, trivial, inefficient solutions, where elegant, more efficient solutionsexist. One
goal of this book is toconvince readers
that algorithm design is an elegantdiscipline, as
well as an important one.The bookis
self-contained. The presentation is mostly intuitive, and technicalities are either kept toa
minimum or are separated from the main discussion. In particular, implementationdetails are
separated from the algorithm-design ideasas
much aspossible. There are many examples of algorithms that were
designed especially
toillustrate the principles emphasized in the book. The material in this book is not
presented as
something to be mastered andmemorized.
It is presented as aseries of ideas, examples,
counterexamples, modifications, improvements, and soon.
Pseudocodesfor most algorithms are given following the descriptions. Numerous exercises and
a discussion
of further reading, with a relevant bibliography, follow each chapter. In mostchapters,
the exercises are divided into two classes, drill exercises andcreative exercises.
Drill exercises are meant to test the reader's understanding of thespecific examples
and algorithms presented in that chapter.Creative exercises
are meant to test thereader's
ability to use the techniquesdeveloped
in that chapter, in addition to theparticular algorithms, to solve new problems. Sketches of solutions to
selected exercises
(those whose numbers are underlined)
are
given at the end of the book. The chaptersalso include a summary
of
the main ideas introduced.The
book is organized as
follows. Chapters 1 through 4 present introductorymaterial. Chapter 2 is
an introduction to mathematical induction.Mathematical
induction is, as we will see, very important to algorithm design. Experience with
induction
proofs is therefore
very helpful. Unfortunately, few computer-science studentsget enough exposure to induction proofs. Chapter 2 may be quite difficult for some students.
We suggest
skipping the more difficult examples at first reading, and returning to them later.Chapter 3 is
an introduction to the analysisof
algorithms. It describes the processof
analyzing algorithms, and gives thebasic tools
one needs to be able toperform
Preface
viisimple analysis of the algorithms
presented
in the book. Chapter 4 isa brief
introduction to data structures. Readers who are familiar with basic data structures and who have abasic
mathematical background can start directly fromChapter 5
(it is always agoodidea
to read
the introduction though). Chapter 5presents
the basic ideas behind theapproach
of
designing algorithms through the analogy to induction proofs. It gives severalexamples of
simple algorithms, and describes theircreation. If
you read only one chapterin this book, read Chapter
5.
There
are two basic ways toorganize a book
on algorithms. One way is todivide
the book according to the
subject of
the algorithms, for example, graph algorithms,geometric
algorithms. Another way istodivide
the book according to designtechniques.
Even though the emphasis of this book is on design
techniques, I have chosen
the formerorganization. Chapters 6 through 9 present algorithms in four areas: algorithms for
sequences
and sets (e.g., sorting, sequencecomparisons, data compression),
graphalgorithms (e.g., spanning trees, shortest paths, matching), geometric algorithms (e.g.,
convex
hull, intersection problems), and numerical and algebraic algorithms (e.g., matrixmultiplication, fast Fourier transform). I believe that this organization is clearer and
easier to follow.
Chapter 10 is devoted to
reductions.
Although examples of reductions appear inearlier chapters, the subject is unique and important enough to warrant a chapter of its
own.
This chapter also serves as
an opening act to Chapter11,
which deals with the subjectof NP-completeness.
This aspect of complexity theory hasbecome
an essential part of algorithm theory. Anyone who designs algorithms should know about NP- completeness and the techniques for proving this property.Chapter 12is
an introduction to parallel algorithms. It contains several interesting algorithms under different models of parallelcomputation.
The
material in this book ismore
than can be covered in a one-semester course,which
leaves
many choices for the instructor. A first course in algorithmdesign
shouldinclude parts of Chapters
3, 5, 6, 7,
and 8 in some depth, although not necessarily all ofthem. The
more advanced parts of thesechapters, along
with Chapters 9, 10, 11,and 12,are optional for
a
first course, and can beused as a basis
for a more advanced course.Acknowledgments
First and foremost I thank my wife Rachel for helping me in more ways than I can list
here throughout this adventure. She was instrumental in the development of the
methodology on which the
book is based. She
contributed suggestions, corrections, and\342\200\224more important than anything else \342\200\224sound advice. I could not
have done
it without her.Special thanks
are due to
Jan van Leeuwen for an excellent and thorough review of a large portion of this book. Hisdetailed comments,
numerous suggestions, and many correctionshave
improved the book enormously. Ialso thank Eric Bach, Darrah Chavey,Kirk Pruhs, and Sun Wu, who read parts of the manuscript and made many helpful
comments,
and the reviewers Guy T.Almes (Rice
University), Agnes H. Chan (Northeastern University), Dan Gusfield (University ofCalifornia, Davis),
David Harel(Weizmann Institute, Israel),
Daniel Hirschberg
(University of California, Irvine),viii Preface
Jefferey H. Kingston (University of Iowa), Victor Klee (University of Washington), Charles Martel (University of California, Davis), Michael
J.
Quinn (University of New Hampshire), andDiane M. Spresser
(James Madison University).I thank the
people
at Addison-Wesley who failed tosupply pie with any examplesof
horror stories that authors areso fond of
telling. They were very helpful andincredibly patient and understanding. In particular, I thank my production supervisor
Bette Aaronson, my
editor
Jim DeWolf, and my copyeditor
Lyn Dupr6, who not only guidedme
but also let me do things my way even when they knew better. I also thankthe National Science Foundation for financial support, through a Presidential Young
Investigator Award, and AT&T, Digital Equipment Corporation, Hewlett Packard, and
Tektronix, for matching funds.
The book
was designed and typeset by me. It was formatted in troff, and printedon a Linotronic 300 at the Department of Computer
Science,
University of Arizona. I thank RalphGriswold for his advice,
and John Luiten, Allen Peckham, and AndreyYeatts for technical help with the typesetting. The figures
were prepared
with gremlin \342\200\224 developed at the Universityof California,Berkeley
\342\200\224except for Fig. 12.22, which was
designed and drawn by Gregg Townsend. The index was
compiled
with the help of asystem
by Bentley and Kernighan [1988]. Ithank Brian Kernighan for supplyingme
the code within minutes after I(indirectly) requestedit.
The cover was done by MarshallHenrichs, based
on an idea by the author.I must stress, however, that the final manuscript was
prepared
by the typesetter.He was the one who decided to
overlook
many comments and suggestions of the people listed here. And he isthe one who should bear the consequences.Tucson, Arizona Udi
Manber
(Internet address: [email protected].)
CONTENTS
Chapter 1 Chapter 2
Chapter 3
Introduction l
Mathematical
Induction 9
2.1 2.2 2.3 2.4 2.5 2.6
2.7 2.8 2.9 2.10 2.11
2.12 2.13 2.14
Introduction
Three Simple Examples
Counting
Regions
in the PlaneASimple
Coloring Problem
A More Complicated Summation Problem
A Simple Inequality Euler's Formula
A Problem in Graph Theory
Gray
Codes
Finding Edge-Disjoint Paths in a Graph
Arithmetic versus Geometric Mean Theorem
Loop
Invariants: Converting aDecimal Number toBinaryCommon Errors
Summary
Bibliographic
Notes and
Further Reading ExercisesAnalysis of
Algorithms 37
3.1 3.2 3.3 3.4 3.5
3.6
3.7
Introduction The 0 Notation
Time and Space
Complexity SummationsRecurrence Relations 3.5.1 Intelligent Guesses
3.5.2 Divide and
Conquer Relations 3.5.3
Recurrence Relations with Full History UsefulFacts
Summary
Bibliographic Notes and Further Reading
Exercises
9 11 13 14 15 16 17 18 20 23
24 26 28 29 30
31
37 39 42 43 46 47 50 51 53 55 55 56
IX
x Contents
Chapter 4
Data Structures 61
4.1 4.2
Introduction
Elementary Data Structures 4.2.1
Elements
Arrays Records Linked Lists 4.3
4.2.2 4.2.3 4.2.4
Trees 4.3.1 4.3.2 4.3.3 4.3.4
4.4 4.5 4.6 4.7
Representation of Trees
Heaps
Binary
Search Trees
AVL Trees
Hashing
The Union-Find
Problem Graphs
Summary
Bibliographic Notes and Further Reading
Exercises
Chapter 5 Designof
Algorithms by Induction 915.1 Introduction
5.2 Evaluating Polynomials 5.3
Maximal Induced
Subgraph5.4 Finding One-to-One Mappings
5.5 The
Celebrity Problem5.6 A Divide-and-Conquer Algorithm: The Skyline Problem 5.7
Computing Balance
Factors in Binary Trees5.8 Finding the Maximum Consecutive Subsequence
5.9
Strengthening the Induction Hypothesis5.10
Dynamic
Programming: The Knapsack Problem 5.11Common Errors
5.12
SummaryBibliographic Notes and Further Reading
Exercises
Chapter 6
Algorithms Involving Sequences and Sets119 6.1
Introduction6.2 Binary Search and Variations 6.3 Interpolation Search
6.4 Sorting
6.4.1 Bucket Sort and Radix Sort
6.4.2 Insertion Sort and Selection Sort 6.4.3 Mergesort
61 62 62 63 63 64 66 67 68 71
75 78 80 83 84
85 86
91 92 95 96 98 102 104 106
107 108 111 112 113
114
119
120
125
127
127
130 130
Contents xi
6.4.4 Quicksort 131
6.4.5 Heapsort 137
6.4.6
A Lower Bound for Sorting141
6.5
Order Statistics 1436.5.1 Maximum and Minimum Elements 143
6.5.2 Finding the fcth-Smallest Element 144
6.6 Data
Compression 1456.7 String Matching
148
6.8 Sequence
Comparisons 1556.9 Probabilistic Algorithms
158
6.9.1
Random Numbers 1606.9.2 A
Coloring Problem 161
6.9.3
A Technique for Transforming ProbabilisticAlgorithms into Deterministic Algorithms 161
6.10
Finding a Majority 1646.11
Three Problems
Exhibiting Interesting Proof Techniques 1676.11.1 Longest
Increasing Subsequence 1676.11.2 Finding the Two Largest Elements in a Set 169
6.11.3
Computing
the Mode of aMultiset171
6.12
Summary 173Bibliographic Notes and Further Reading 173
Exercises 175
Chapter 7 Graph
Algorithms 1857.1 Introduction 185
7.2
Eulerian Graphs 1877.3 Graph
Traversal 189
7.3.1
Depth-First Search 1907.3.2 Breadth-First
Search 198
7.4
Topological Sorting 1997.5 Single-Source
Shortest
Paths 2017.6 Minimum-Cost Spanning
Trees 208
7.7
All Shortest Paths 2127.8 Transitive
Closure 214
7.9
Decompositions of Graphs 2177.9.1
Biconnected Components 217
7.9.2
Strongly Connected Components 226 7.9.3Examples of
the Use of Graph Decomposition230
7.10
Matching 2347.10.1 Perfect Matching in Very Dense Graphs .234
7.10.2
Bipartite Matching 2357.11 Network
Flows 238
7.12
Hamiltonian Tours 2437.12.1 Reversed Induction 244
xii Contents
7.12.2 Finding Hamiltonian Cycles in Very
Dense Graphs
7.13
SummaryBibliographic Notes and Further Reading
Exercises
Chapter 8 Geometric
Algorithms 2658.1 8.2 8.3
8.4
8.5 8.6 8.7
Introduction
Determining Whether a Point
Is Insidea
PolygonConstructing Simple Polygons
Convex Hulls
8.4.1 A Straightforward Approach
8.4.2
Gift Wrapping 8.4.3 Graham's ScanClosest Pair
Intersections
of Horizontal and Vertical LineSegments
Summary
Bibliographic Notes and Further Reading
Exercises
244 246 247 248
265 266 270
273 273 274 275 278
281 285 286 287 Chapter 9
Algebraic and Numeric Algorithms 2939.1 9.2 9.3 9.4 9.5
9.6
9.7
Introduction Exponentiation Euclid's Algorithm Polynomial Multiplication Matrix Multiplication 9.5.1 Winograd's Algorithm 9.5.2 Strassen's Algorithm 9.5.3
Boolean Matrices
The Fast Fourier Transform Summary
Bibliographic Notes
and Further Reading ExercisesChapter
10 Reductions 321
10.1
Introduction10.2 Examples of Reductions
10.2.1
A Simple String-Matching Problem 10.2.2Systems of
Distinct Representatives10.2.3 AReduction Involving Sequence Comparisons 10.2.4 Finding a
Triangle
in Undirected Graphs 10.3 Reductions Involving Linear Programming10.3.1 Introduction and Definitions
10.3.2 Examples of Reductions to
Linear
Programming293 294 297 298
301 301 301
304 309 316 316 317
321 323
323 323 324 325 327
327
329
Contents
xiii10.4 Reductions for Lower
Bounds 331
10.4.1
A Lower Bound for FindingSimple Polygons 331 10.4.2
Simple Reductions Involving Matrices 33310.5 Common Errors 334
10.6
Summary 336Bibliographic Notes and Further Reading 336
Exercises 337
Chapter 11 NP-Completeness 341
11.1
Introduction 34111.2 Polynomial-Time Reductions
342
11.3
Nondeterminism and Cook's Theorem 34411.4 Examples
of NP-Completeness Proofs 34711.4.1 Vertex
Cover 348
11.4.2
Dominating Set 34811.4.3 3SAT
350
11.4.4 Clique 351
11.4.5
3-Coloring 35211.4.6 General Observations
355
11.4.7
More NP-Complete Problems 35611.5
Techniques For Dealing
with NP-Complete Problems 35711.5.1
Backtracking and Branch-and-Bound 358
11.5.2
Approximation Algorithms with GuaranteedPerformance
363
11.6
Summary 368Bibliographic Notes and Further Reading 368
Exercises 370
Chapter 12 Parallel
Algorithms 37512.1 12.2 12.3
12.4
Introduction
Models of Parallel Computation
Algorithms for Shared-Memory Machines
12.3.1
Parallel
Addition12.3.2 Maximum-Finding Algorithms
12.3.3
The Parallel-Prefix
Problem12.3.4 Finding Ranks in Linked Lists
12.3.5 The
Euler's Tour
TechniqueAlgorithms for Interconnection Networks
12.4.1
Sorting on an Array 12.4.2 Sorting Networks12.4.3 Finding the
fcth-Smallest
Element on aTree 12.4.4 Matrix Multiplication on the Mesh12.4.5
Routing in a Hypercube375
376 378 379 380 382
385 387 389 390 393
396
398
401
xiv Contents
12.5
12.6
References
Index
Systolic
Computation12.5.1 Matrix-Vector Multiplication
12.5.2
The
Convolution Problem 12.5.3 Sequence Comparisons SummaryBibliographic Notes
and Further ReadingExercises
tions
to Selected Exercises 417
445
465 404 404 405
407
409
409
411
CHAPTER 1
INTRODUCTION
Great importance has been rightly attached to thisprocess
of
\"construction,\" and some claim tosee
in it thenecessary and sufficient condition of the progress
of
theexact sciences. Necessary, no doubt, but not sufficient!
For
a
construction to be useful and not mere waste ofmental effort,for it to serve as astepping-stone to higher things, it must first of allpossess
a
kind of unity enabling usto see something more than the juxtaposition of its elements.
Henri Poincare, 1902
The Webster's Ninth New Collegiate dictionary defines an algorithm as \"aprocedure for solving
a
mathematical problem (as of finding thegreatest common divisor)
in a finitenumber of
steps
that frequently involves a repetitionof
an operation; or broadly, astep- by-step
procedure for solving a problemor accomplishingsome end.\"
We will stick to thebroad
definition. The design of algorithms isthus an old field of study. People have always beeninterested
in finding better methods toachieve
their goals, whether those bestarting fires, building pyramids, orsorting the mail. The study
of computer
algorithms isof course new.
Some computer
algorithms use methods developed before the invention of computers, butmost problems
require new approaches. For one thing, it is not enough to tella computer to \"look over
the hill and sound the alarm ifan army is advancing.\"A
computer
must know the exact meaningof
\"look,\" how to identify an army, and howto sound the alarm
(for some
reason, sounding an alarm is always easy). A computer receives its instructions via well-defined, limited primitive operations. It is a difficult process to translate regular instructions to a language that a computer understands. Thisnecessary process,called
programming, is now performed onone level or
another by millions of people.2 Introduction
Programming a computer, however, requires
more
than just translating well-understood instructions to alanguage a
computer can
understand. In most cases, weneed to devise
totally new methods for solvinga problem.
It is not just learning the weirdlanguage in which we \"talk\" to a computer that makes it hard to program; it is knowing what to
say. Computers execute
not only operations that were previouslyperformed
byhumans; with their enormous
speed, computers can do
much more than was everpossible.
Algorithms of the past dealt with dozens, maybe hundreds ofitems, and,
atmost, with thousands of instructions. Computers can deal with billions, or even trillions,
of
bits of information, and canperform
millions of (their primitive) instructionsper second.
Designing algorithms on this orderof
magnitude is something new. It is in many respects counterintuitive. Weare used
to thinking in terms of things we can see andfeel.
As a result, there isa tendency
when designing an algorithm touse
thestraightforward approach that works very well for small problems. Unfortunately,
algorithms that work well for
small problems
may be terrible for largeproblems.
It iseasy to lose sight of the complexity and inefficiency of an algorithm when
applied to
large-scale
computations.There is another aspect to this problem. The algorithms we
perform
in our dailylife are not too complicated and are not performed too often. It isusually not worthwhile to expend
a
lot of effort to develop the perfect algorithm. The payoff istoo small.
Forexample, consider the problem
of
unpacking grocery bags. There are obviouslyless
efficient
and more efficient ways of doing it, depending on the contentsof
the bags and the way the kitchen is organized.Few people spend
time even thinking about thisproblem,
much less developing algorithms for it. On the other hand,people
who dolarge-scale commercial packing and unpacking must develop good
methods.
Anotherexample is mowing the lawn. We can improve the mowing by minimizing the number
of
turns, the total time for mowing,
or
the length of the trips to the garbage cans. Again,unless
one
really hates mowing the lawn,one
would not spend an hour figuring out howto save
a
minute of mowing. Computers, on the other hand, can deal with verycomplicated tasks, and they may have to perform
those tasks
many times. It isworthwhile to
spend a
lot of time designing bettermethods, even
if the resulting algorithms aremore complicated
and harder to understand. The potential of a payoff is muchgreater. (Of course,
we should not overoptimize, spending hours of programming time tosave overall a
few seconds of computer time.)These
two issues \342\200\224the need for counterintuitiveapproaches to large-scale
algorithms and the possible complexities
of these
algorithms \342\200\224point to the difficulties in learning this subject. First, wemust realize that straightforward intuitive methods
are
notalways the best. It isimportant to continue the search for better
methods. To do
that, weneed of course, to learn new methods. This book surveys and illustrates numerous methods for algorithm design. But it is not enough to learn even
a large
number ofmethods, just as it is not enough to
memorize
many games of chess in order to be agood player. One
must understand the principles behind the methods. One must know how to apply them and,more
important, when to apply them.A design and implementation of an algorithm is analogous to a
design
andIntroduction 3
construction of
a house.
We start with the basicconcepts, based
on the requirements for thehouse.
It is the architect's job topresent a
plan that satisfies the requirements. It isthe engineer's job to
make sure
that the plan isfeasible and correct (so that thehouse
willnot collapse after ashort while). It is then the builder's job to construct the house based on these
plans. Of course,
all along the way, thecosts associated
with each step must be analyzed and taken into account. Eachjob is
different, but they are all related andintertwined. A design of an algorithm also starts with the basic ideas and
methods.
Then,a
plan is made. We mustprove
the correctness of the plan and make sure that itscost is effective.
The last step is toimplement
the algorithm for a particularcomputer.
Risking oversimplification, we can divide the process into four steps:
design, proof
ofcorrectness, analysis, and implementation. Again, each of these steps is different, but
they are all related. None
of
them can be made in a vacuum, without a regard to theothers. One rarely goes through these steps in linear
order.
Difficulties arise in allphases
of
the construction. They usually requiremodifications to
the design, which in turn require another feasibility proof, adjustment ofcosts, and change
of implementation.This book concentrates on the first step, the design
of
algorithms. Following our analogy, thebook could
have been entitled The Architectureof
Algorithms. However, computer architecture hasa
different meaning, so using this term would be confusing.The book
does
not, however, ignore all the otheraspects.
A discussion of correctness,analysis, and implementation follows the description
of most
algorithms \342\200\224in detail for some algorithms, briefly for others. The emphasis is onmethods of design.
It is not enough tolearn many algorithms to be
a good
architect and to be able todesign
new algorithms. One must understand the principles behind the design.We employ a
different way of explaining algorithms in this book. First, we try to lead the reader to find his or her own solution; we strongly believe that thebest
way to learn how tocreate
something is to try tocreate
it. Second, and more important, we followa
methodology for designing algorithms that helps this creative process. The methodology,
introduced in Manber [1988], provides an elegant intuitive framework for explaining the
design of algorithms in more depth. It also
provides a
unified way to approach thedesign. The
different methods that are encompassed by this methodology, and their numerous variations, are instances of thesame technique.
The process of choosing amongthose
many possible methods and applying thembecomes more methodical.
Thismethodology does not cover all
possible
ways of designing algorithms. It is useful,however, for a great majority of the algorithms in this book.
The methodology is
based on
mathematical induction. The heart of it lies in an analogybetween
the intellectual process of provingmathematical theorems
and that ofdesigning combinatorial
algorithms. The
main idea in the principleof
mathematical induction is that astatementneed
not be proven from scratch: It is sufficient to show that the correctness of the statementfollows
from the correctness of thesame
statement forsmaller instances and the correctness of the statement for a
small base case.
Translating this principle to algorithmdesign suggests
an approach that concentrates on extending1The two wonderful books by Tracy Kidder, The Soul of a NewMachine (Little Brown, 1981), and House
(Houghton Mifflin, 1985), inspired thisanalogy.