Professional Documents
Culture Documents
to
Computer Science
Robert Sedgewick
Kevin Wayne
Princeton University
For information on obtaining permission for use of material from this work, please submit
a request to the authors at rs@cs.princeton.edu and wayne@cs.princeton.edu
Preface
ii
Coverage
The book is organized around four areas of computer science: programming,
architecture, theory, and systems. We introduce fundamental concepts in each
area and pay special attention to relationships among them. A proper introduction to the field must do justice to each of these four areas. We also cover
applications in scientific computing throughout the book, to reinforce and
supplement the curriculum that is typically taught to students in mathematics,
science, and engineering in high school and their first year in college.
Programming is essential to being able to understand and appreciate
computer science. We cover basic programming in Java, abstract data types
and Java classes, elementary data structures, and the design and analysis of
algorithms. To teach these concepts, we use sample programs that solve
interesting problems supported with exercises ranging in difficulty from selfstudy drills to challenging problems that call for creative solutions. Whenever
possible, we draw examples from concepts to be covered elsewhere in the
book or from scientific or commercial applications. Students who learn the
programs in this book will have the solid foundation necessary to prepare
them to be able to effectively use computers as they pursue any academic discipline.
Architecture refers both to the art of designing computers and to the
process of building them. Our coverage of this topic is centered around an
imaginary machine that is similar to real computers. We specify the machine
in full detail, consider machine-language programs for familiar tasks, and
present a Java simulator for the machine. We continue with a treatment of
circuits and logical design, culminating in a description of how such a
machine might be built from the ground up. Our intent is to demystify this
apparently formidable challenge while also providing a context for under-
iii
standing how Java programming and other familiar high-level tasks relate to
actual machines.
Theory helps us to understand the limits on what we can accomplish
with computers. We present Turings classical results that show how simple
abstract machines can help us to pose fundamental questions about the
nature of computation. Some of these are among the most important scientific questions of our time. We also consider practical applications such as
how to estimate the running times of our programs and how to design efficient algorithms.
Systems enable us to work with computers at a high level of abstraction. We describe the basic components of computer systems that support
programming; operating systems for interacting with our programs and our
data; networks that allow interaction among computers; and applications
systems that provide specialized support for particular tasks.
Our coverage of the four areas is intertwined and also threaded with
descriptions and examples of various classical algorithms, programming languages, scientific computing, and commercial applications. Where relevant,
we also provide proper historical perspective.
Generally speaking, we introduce material that is covered, at most
colleges and universities, in several later computer science courses. For computer science majors, this breadth of coverage provides a foundation to be
reinforced in later courses. For students in other fields who have a chance to
take only one or two courses in computer science, this introduction to programming, architecture, theory and systems in the context of scientific applications gives the background that they need to effectively address the impact
of computer science on their chosen fields.
iv
Prerequisites
Our aim is for the book to be suitable for typical first-year science
and engineering students. Accordingly, we do not expect preparation significantly different from other entry-level science and mathematics courses.
Learning to program is one of our primary goals, so we assume no
prior programming experience. Indeed, one of the most important features
of our approach is that we integrate teaching programming with teaching the
rest of computer science. But what should be done with students who have
already taken a programming course, in high school or in college? Actually
the material in this book is ideal for such students. They can review the mate-
vi
Goals
What can instructors of upper-level courses in science and engineering expect
of students who have successfully completed a course based on this book?
Anyone who has taught an introductory computer science course
knows that expectations are typically high: each instructor expects all students to be familiar with the computing environment and approach that he
or she wants to use. A physics professor might expect some students to learn
to program over the weekend to run a simulation; an engineering professor
might expect other students to be using a particular package to numerically
solve differential equations; or a computer science professor might expect
knowledge of the details of a particular programming environment. Is it realistic to expect to be able to meet such diverse expectations? Should there be a
different introductory course for each set of students? Colleges and universities have been wrestling with such questions since computers came into widespread use in the latter part of the 20th century.
Our primary goal is to provide an answer to such questions by developing a common introductory course in computer science for all students in
science and engineering (including prospective computer science majors)
that is analogous to commonly-accepted introductory courses in mathematics, physics, biology, and chemistry. The course may also be suitable for students in the humanities who wish a full introduction to the field.
Students who master the material in this book gain the confidence
and knowledge that they need to be able to learn to exploit computers wherever they might appear later in their careers, whether it be using an integrated
mathematical software package to attack advanced mathematical problems,
using Java to develop innovative applications, writing code to control sophisticated devices, using simulation to study complex problems, or developing
new computational paradigms. People continually need to be able to develop
new skills in particular contexts because computers continue to evolve.
Instructors teaching students who have studied from this book can expect
that they have the background and experience necessary to make it possible
for them to acquire such skills, to effectively exploit computers in diverse
applications, and to appreciate their limitations.
vii
Booksite
An extensive amount of information that supplements this text may be found
on the world-wide web at
http://www.cs.princeton.edu/IntroCS
For economy, we refer to this web site as the booksite throughout. It contains
material oriented towards instructors, students, and casual readers of the
book. We briefly describe this material here, though, as all web users know, it
is best surveyed by browsing. With a few exceptions to support testing, the
material is all publicly available.
One of the most important implications of the booksite is that it
empowers instructors and students to use their own computers to teach and
learn the material in this course. Anyone with a computer and a browser can
begin learning computer science and learning to program, by following a few
instructions on the booksite. The process is no more difficult than downloading a media player or a new computer game.
For instructors, the booksite contains information about teaching the
course. This information is primarily organized around a teaching style that
we have developed over the past decade, where we offer two lectures per week
to a large audience, supplemented by two class sessions per week where students meet in small groups with instructors or teaching assistants. The booksite has presentation slides for the lectures, which set the tone for the course.
We assign weekly problem sets based on exercises from the book and
programming assignments, also based on exercises from the book, but with
much more detail. Each programming assignment is intended to teach a relevant concept in the context of an interesting application while presenting an
ambitious and interesting challenge to each student. The progression of
assignments embody our approach to teaching programming. The booksite
fully specifies all the assignments and provides detailed, structured information to support teaching students to complete them in the alloted time,
including code for strawman solutions, descriptions of suggested approaches,
and outlines for what should be taught in class sessions.
The booksite also includes webware for use in managing student submissions and grading assignments.
viii
For students, the booksite contains quick access to much of the material in the book, plus extra material to encourage self-learning. Solutions are
provided for many of the books exercises, including complete program code
and text data. There is a wealth of information associated with programming
assignments, including suggested approaches, checklists, FAQs, and test data.
For casual readers (including instructors and students!) the booksite
is a resource for accessing all manner of extra information associated with the
books content. All of the booksite content provides web links and other
routes to pursue to find more information about the topic under consideration. There is far more information accessible than any individual could
fully digest, but our goal is to provide enough to whet any readers appetite
for more information about the books content.
As with any web site, our Introduction to Computer Science booksite is
continually evolving, but it is an essential resource for everyone who owns
this book. In particular, the supplemental materials supporting teaching and
learning within a first-year college course are critical to our goal of making
computer science an integral component of the education of all scientists and
engineers.
Acknowledgements
ix
Contents
1
Overview . . . . . . . . . . . . . . . . . . .1
1.1
1.2
1.3
1.4
Elements of Programming . . . . . . . . . 21
2.1
2.1
2.2
2.3
2.4
2.5
2.6
A Simple Machine 1
Applications 1
Analysis 1
Context 1
239
xi
Systems . . . . . . . . . . . . . . . . . . 387
8.1
8.2
8.3
8.4
8.5
10
441
xii
Overview
1.1
A Simple Machine
1.2
Applications
1.3
Analysis
1.4
Context
Overview
Elements of Programming
Our goal in this chapter is to convince you that writing a program is easier
than writing a piece of text such as a paragraph or an essay. Writing prose is
difficult: we spend many years in school to learn how to do it. By contrast, just
a few building blocks suffice to take us into a world where we can harness the
computer to help us solve all sorts of fascinating problems that would be otherwise unapproachable. In this chapter, we take you through these building
blocks, get you started on programming in Java, and study a variety of interesting programs. You will have an additional avenue to be able to express yourself
(writing programs) within just a few weeks. Like the ability to write prose, the
ability to program is a lifetime skill that you can continually refine and is certain to serve you well into the future.
You will learn the Java programming language, but that will be much
easier to do than learning a foreign language that is unfamiliar to you.
Indeed, programming languages are characterized by no more than a few
dozen vocabulary words and rules of grammar. Most of the material that we
cover in this chapter could apply to the C or C++ languages, or any of several
other modern programming languages, but we describe everything specifically in Java so that you can get started creating and running programs right
away. On the one hand, to the extent possible, we will focus on learning to
program, as opposed to learning details about Java. On the other hand, part
of the challenge of learning to program is knowing which details are relevant
in a given situation. Java is widely available, but also learning to program in
Java will make it easy for you learn to program in another language.
21
Elements of Programming
22
2.1
In this section, our plan is to lead you into world of Java programming by taking you through the basic steps required to get a simple program running. The
Java system is a collection of applications not unlike any of the other applications that you are accustomed to using (such as your word processor, e-mail
program, or internet browser). As with any application, you need to be sure
that Java is properly installed on your computer. It comes preloaded on may
computers and is easy to download. You also need an editor and a terminal
application (see Appendix X).
Programming in Java. To introduce you to developing computer programs written in Java, we break the process down in to three steps. To program in Java you need to:
1.
2.
3.
In the first step, you start with a blank page and end with a sequence of typed
characters on the page, just as when you write an e-mail or a paper. In the second step, you use a system application called a compiler that translates your
program into a form more suitable for the computer (and puts the result in a
file named MyProgram.class). In the third step, you transfer control of the
computer from the system to your program (which returns control back to
the system when finished).
Creating a program. A program is nothing more than a sequence of characters, like a sentence, a paragraph, or a poem. To create one, therefore, we
need only define that sequence of characters, in the same way as we do for email or any other computer application. Programmers usually use a simple
editor for this task with a fixed-width font to make it easier to line things up
vertically in the code.
Compiling a program. At first, it might seem to you as though the Java
programming language is designed to be best understood by the computer.
Actually, to the contrary, the language is designed to be best understood by
23
Elements of Programming
24
% javac HelloWorld
% java HelloWorld
Hello, World
cuted, one by one, when the method is invoked. One type of statement is a
method name with, in parentheses, zero or more arguments. When we write
a such a statement, we are simply saying that we want to run that method
(and to provide it with some information, in the arguments). This process is
known as invoking or calling the method. In HelloWorld, the main method
consists of a single statement that calls the Java library method System.out.println(). The name of the method is println(); the name of
the library is System.out. You will be writing programs that use calls to many
different Java library methods, and you refer to each of them in just this way.
In Program 2.1.1, System.out.println() takes the message Hello, World
as its argument and prints it to the terminal. We do not need to know the
details of how System.out.println() accomplishes this taskwe can simply rely on it to do so. The method main() itself takes an argument, which we
will discuss soon as the focus of Program 2.1.2.
At first, accomplishing the task of printing something out in a terminal window might not seem very interesting; upon reflection, you will see
that one of the most basic capabilities that we need from a program is for it to
be able to tell us what it is doing.
For the time being, all our program code will be just like
Program 2.1.1, except with a different sequence of statements in main(). We