
Beginning Algorithms (2006)
.pdf

Contents
Acknowledgments |
ix |
Introduction |
xix |
Chapter 1: Getting Started |
1 |
Defining Algorithms |
1 |
Understanding Complexity in Relation to Algorithms |
3 |
Understanding Big-O Notation |
4 |
Constant Time: O(1) |
6 |
Linear Time: O(N) |
6 |
Quadratic Time: O(N2) |
6 |
Logarithmic Time: O(log N) and O(N log N) |
8 |
Factorial Time: O(N!) |
8 |
Unit Testing |
9 |
What Is Unit Testing? |
9 |
Why Unit Testing Is Important |
11 |
A JUnit Primer |
11 |
Test-Driven Development |
14 |
Summary |
14 |
Chapter 2: Iteration and Recursion |
15 |
Performing Calculations |
16 |
Processing Arrays |
18 |
Using Iterators to Overcome Array-based Problems |
18 |
Iterator Operations |
19 |
The Iterator Interface |
20 |
The Iterable Interface |
20 |
Iterator Idioms |
21 |
Standard Iterators |
21 |
Recursion |
35 |
Recursive Directory Tree Printer Example |
37 |
Anatomy of a Recursive Algorithm |
40 |
The Base Case |
40 |
The General Case |
41 |
Summary |
41 |
Exercises |
41 |

Contents
Chapter 3: Lists |
43 |
Understanding Lists |
43 |
Testing Lists |
46 |
Implementing Lists |
58 |
An Array List |
59 |
A Linked List |
66 |
Summary |
74 |
Exercises |
74 |
Chapter 4: Queues |
75 |
Understanding Queues |
75 |
Queue Operations |
76 |
The Queue Interface |
77 |
A First-In-First-Out Queue |
77 |
Implementing the FIFO Queue |
81 |
Blocking Queues |
82 |
Example: A Call Center Simulator |
86 |
Running the Application |
95 |
Summary |
96 |
Exercises |
96 |
Chapter 5: Stacks |
97 |
Stacks |
97 |
The Tests |
99 |
Implementation |
102 |
Example: Implementing Undo/Redo |
105 |
Testing Undo/Redo |
106 |
Summary |
114 |
Chapter 6: Basic Sorting |
115 |
The Importance of Sorting |
115 |
Sorting Fundamentals |
116 |
Understanding Comparators |
116 |
Comparator Operations |
117 |
The Comparator Interface |
117 |
Some Standard Comparators |
117 |
Working with the Natural Comparator |
117 |
Working with the Reverse Comparator |
119 |
Understanding Bubble Sort |
121 |
xii

|
Contents |
The ListSorter Interface |
124 |
Testing AbstractListSorter |
124 |
Working with a Selection Sort |
128 |
Understanding Insertion Sort |
133 |
Understanding Stability |
138 |
Comparing the Basic Sorting Algorithms |
139 |
CallCountingListComparator |
139 |
ListSorterCallCountingTest |
140 |
Understanding the Algorithm Comparison |
143 |
Summary |
144 |
Exercises |
144 |
Chapter 7: Advanced Sorting |
145 |
Understanding the Shellsort Algorithm |
145 |
Understanding Quicksort |
151 |
Understanding the Compound Comparator and Stability |
157 |
Understanding the Mergesort Algorithm |
160 |
Merging |
160 |
The mergesort Algorithm |
162 |
Comparing the Advanced Sorting Algorithms |
169 |
Summary |
172 |
Exercises |
172 |
Chapter 8: Priority Queues |
173 |
Understanding Priority Queues |
174 |
A Simple Priority Queue Example |
174 |
Working with Priority Queues |
179 |
Understanding the Unsorted List Priority Queue |
182 |
Understanding the Sorted List Priority Queue |
184 |
Understanding Heap-ordered Priority Queues |
186 |
Sink or Swim |
188 |
Comparing the Priority Queue Implementations |
194 |
Summary |
198 |
Exercises |
198 |
Chapter 9: Binary Searching and Insertion |
199 |
Understanding Binary Searching |
199 |
Binary Search Approaches |
202 |
A List Searcher |
202 |
Recursive Binary Searcher |
205 |
xiii

Contents
Iterative Binary Searcher |
208 |
Assessing the List Searcher’s Performance |
210 |
Linear Searching for Comparison |
210 |
Tests for Performance |
212 |
Understanding Binary Insertion |
216 |
A List Inserter |
217 |
Assessing Performance |
220 |
Summary |
224 |
Chapter 10: Binary Search Trees |
225 |
Understanding Binary Search Trees |
226 |
Minimum |
227 |
Maximum |
227 |
Successor |
227 |
Predecessor |
227 |
Search |
228 |
Insertion |
230 |
Deletion |
232 |
In-order Traversal |
235 |
Pre-order Traversal |
235 |
Post-order Traversal |
235 |
Balancing |
236 |
Testing and Implementing a Binary Search Tree |
238 |
Assessing Binary Search Tree Performance |
261 |
Summary |
264 |
Exercises |
264 |
Chapter 11: Hashing |
265 |
Understanding Hashing |
265 |
Working with Hashing |
272 |
Linear Probing |
275 |
Bucketing |
281 |
Assessing Performance |
285 |
Summary |
291 |
Exercises |
292 |
Chapter 12: Sets |
293 |
Understanding Sets |
293 |
Testing Set Implementations |
297 |
xiv

|
Contents |
A List Set |
303 |
A Hash Set |
305 |
A Tree Set |
309 |
Summary |
315 |
Exercises |
316 |
Chapter 13: Maps |
317 |
Understanding Maps |
317 |
Testing Map Implementations |
322 |
A List Map |
329 |
A Hash Map |
333 |
A Tree Map |
337 |
Summary |
343 |
Exercises |
344 |
Chapter 14: Ternary Search Trees |
345 |
Understanding Ternary Search Trees |
345 |
Searching for a Word |
346 |
Inserting a Word |
350 |
Prefix Searching |
351 |
Pattern Matching |
353 |
Putting Ternary Search Trees into Practice |
357 |
Crossword Helper Example |
370 |
Summary |
374 |
Exercise |
374 |
Chapter 15: B-Trees |
375 |
Understanding B-Trees |
375 |
Putting B-Trees into Practice |
381 |
Summary |
392 |
Exercises |
393 |
Chapter 16: String Searching |
395 |
A Generic String Searcher Interface |
395 |
A Generic Test Suite |
397 |
A Brute-Force Algorithm |
400 |
The Boyer-Moore Algorithm |
402 |
Creating the Tests |
404 |
Implementing the Algorithm |
404 |
xv

Contents
A String Match Iterator |
408 |
Comparing the Performance |
409 |
Measuring Performance |
409 |
How They Compare |
413 |
Summary |
413 |
Chapter 17: String Matching |
415 |
Understanding Soundex |
415 |
Understanding Levenshtein Word Distance |
426 |
Summary |
435 |
Chapter 18: Computational Geometry |
437 |
A Quick Geometry Refresher |
437 |
Coordinates and Points |
437 |
Lines |
438 |
Triangles |
439 |
Finding the Intersection of Two Lines |
440 |
Slope |
441 |
Crossing the y Axis |
442 |
Finding the Intersection Point |
443 |
Finding the Closest Pair of Points |
457 |
Summary |
467 |
Exercises |
467 |
Chapter 19: Pragmatic Optimization |
469 |
Where Optimization Fits In |
469 |
Understanding Profiling |
470 |
The FileSortingHelper Example Program |
471 |
Profiling with hprof |
475 |
Profiling with JMP |
477 |
Understanding Optimization |
479 |
Putting Optimization into Practice |
480 |
Summary |
487 |
Appendix A: Further Reading |
489 |
Appendix B: Resources |
491 |
xvi

|
Contents |
Appendix C: Bibliography |
493 |
Appendix D: Answers to Exercises |
495 |
Index |
541 |
xvii


Introduction
Welcome to Beginning Algorithms, a step-by-step introduction to computing algorithms for the real world.
Developers use algorithms and data structures every day of their working lives. Having a good understanding of these algorithms and knowledge of when to apply them is essential to producing software that not only works correctly, but also performs efficiently.
This book aims to explain those algorithms and data structures most commonly encountered in day-to- day software development, while remaining at all times practical, concise, and to the point, with little or no verbiage to distract from the core concepts and examples.
Who Should Read This Book
The ideal reader of this book is someone who develops applications, or is just starting to do so, and who wants to understand algorithms and data structures. This might include programmers; developers; software engineering students; information systems students; and computer science students.
While this book assumes you have an understanding of computer programming in general, it is also hoped that if you took away the code, you could still read the book cover to cover and follow along— albeit at a largely conceptual level. For this reason, team leaders, architects, and even business analysts might also benefit.
Prerequisite Knowledge
As the code examples are all written in the Java programming language, a working knowledge of Java is likely necessary, as is a familiarity with the standard Java libraries—and with the java.lang package in particular. Also necessary is an understanding of arrays, loops, and so on, and, of course, how to create, compile, and run Java classes.
Over and above the prerequisites mentioned, there is no particular requirement that you have any knowledge of the data structures or the algorithms contained herein.
What You Will Learn
In these pages, you will find detailed explanations, some implementations, example uses, and exercises, all designed to build your understanding to a point where you can use this knowledge in the real world. The examples given are rarely, if ever, academic in nature. Very careful consideration has been given
in each chapter to present you with code that, in most cases, could be used in real-world applications, immediately.