Data Abstraction & Problem Solving with C++ Walls And Mirrors Seventh Edition Frank M. Carrano University of Rhode Island Timothy M. Henry New England Institute of Technology Boston Columbus Indianapolis Hoboken New York San Francisco Amsterdam Cape Town Dubai London Madrid Milan Munich Paris Montreal Toronto Delhi Mexico City Sao Paulo Sydney Hong Kong Seoul Singapore Taipei Tokyo A01_CARR3971_07_SE_FM.indd 1 20/02/16 12:08 AM Vice President and Editorial Director, ECS: Marcia Senior Operations Specialist: Maura Zaldivar-Garcia J. Horton Inventory Manager: Meredith Maresca Executive Editor: Tracy Johnson (Dunkelberger) Marketing Manager: Demetrius Hall Editorial Assistant: Kristy Alaura Product Marketing Manager: Bram Van Kempen Program Manager: Carole Snyder Marketing Assistant: Jon Bryant Project Manager: Robert Engelhardt Cover Designer: Marta Samsel Media Team Lead: Steve Wright Cover Art: © Jeremy Woodhouse/Ocean/Corbis R&P Manager: Rachel Youdelman Full-Service Project Management: John Orr, Cenveo R&P Senior Project Manager: William Opaluch Publisher Services / Nesbitt Graphics, Inc. Credits and acknowledgments borrowed from other sources and reproduced, with permission, in this textbook appear on the appropriate page within text. © 2017 Pearson Education, Inc. Hoboken, New Jersey 07030 All rights reserved. Printed in the United States of America. This publication is protected by Copyright, and permission should be obtained from the publisher prior to any prohibited reproduction, storage in a retrieval system, or transmission in any form or by any means, electronic, mechanical, photocopying, recording, or likewise. To obtain permission(s) to use material from this work, please submit a written request to Pearson PLC, Permissions Department, 330 Hudson St, New York, NY 10013. Many of the designations by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and the publisher was aware of a trademark claim, the designations have been printed in initial caps or all caps. The author and publisher of this book have used their best efforts in preparing this book. These efforts include the development, research, and testing of theories and programs to determine their effectiveness. The author and publisher make no warranty of any kind, expressed or implied, with regard to these programs or the documentation contained in this book. The author and publisher shall not be liable in any event for incidental or consequential damages with, or arising out of, the furnishing, performance, or use of these programs. Pearson Education Ltd., London Pearson Education Australia Ply. Ltd., Sydney Pearson Education Singapore, Pte. Ltd. Pearson Education North Asia Ltd., Hong Kong Pearson Education Canada, Inc., Toronto Pearson Education de Mexico, S.A. de C.V. Pearson Education–Japan, Tokyo Pearson Education Malaysia, Pte. Ltd. Pearson Education, Inc., Hoboken, New Jersey Library of Congress Cataloging-in-Publication Data on file 10 9 8 7 6 5 4 3 2 1 ISBN-10: 0-13-446397-8 www.pearsonhighered.com ISBN 13: 978-0-13-446397-1 A01_CARR3971_07_SE_FM.indd 2 20/02/16 12:08 AM e W m elcome to the seventh edition of Data Abstraction & Problem Solving with C++: Walls and Mirrors. Since the publication of the first edition, we all have gained experience with teaching data abstraction in an object- o oriented way using C++. This edition reflects that experience and the many comments and suggestions received c from faculty and students alike. l I am pleased to continue working with my co-author, Dr. Timothy Henry, who adds his professional e experience with C++ and attention to pedagogy to our presentation. Our goal remains to give students a W superior foundation in data abstraction, object-oriented programming, and other modern problem- solving techniques. All C++ code has been updated to use exceptions, follow safe and secure coding tech- niques such as those described in the SEI CERT Coding Standards, and use C++11 and C++14 features. We hope that you enjoy reading this book. Like many others before you, you can learn—or teach— data structures in an effective and sustainable way. Talk to Us Walls and Mirrors continues to evolve. Your comments, suggestions, and corrections will be greatly appre- ciated. Here are a few ways to reach us: • E-mail: [email protected] or [email protected] • Facebook: www.facebook.com/makingitreal • Twitter: twitter.com/Frank_M_Carrano • Blog: frank-m-carrano.com/makingitreal iii A01_CARR3971_07_SE_FM.indd 3 20/02/16 12:08 AM s T t he topics that we cover in this book deal with the various ways of organizing data so that a given application n can access and manipulate data in an efficient way. These topics are fundamental to your future study of com- e puter science, as they provide you with the foundation of knowledge required to create complex and reliable d software. Whether you are interested in designing video games or software for robotic-controlled surgery, the u study of data structures is vital to your success. Even if you do not study all of the topics in this book now, you t are likely to encounter them later. We hope that you will enjoy reading the book, and that it will serve as a useful S reference tool for your future courses. The walls and mirrors in the title represent two fundamental problem-solving techniques that appear o throughout the presentation. Data abstraction isolates and hides the implementation details of a module t from the rest of the program, much as a wall can isolate and hide you from your neighbor. Recursion is a e repetitive technique that solves a problem by solving exactly the same but smaller problems, much as t images in facing mirrors grow smaller with each reflection. o Please be sure to browse the rest of this preface to see the features that will help you in your studies. N To help you learn and to review for exams, we have included such learning aids as video tutorials (VideoNotes), checkpoint questions with answers, margin notes, programming tips, chapter summaries, A and a glossary. As a help during programming, you will find C++ reference material in the appendixes and inside the covers. You should review the list of this book’s features given later in this preface in the section “Features to Enhance Learning.” The presentation makes some basic assumptions about your knowledge of C++. Some of you may need to review this language or learn it for the first time by consulting the appendixes of this book. This book covers C++ classes and other relevant aspects of the language in C++ Interludes that occur through- out the book between certain chapters. These interludes do not assume that you already know their topics. We assume no experience with recursive functions, which are included in Chapters 2 and 5. All of the C++ source code that appears in this book is available for your use. Later in this preface, the description of supplementary materials tells you how to obtain these files, as well as the VideoNotes and other online documents. iv A01_CARR3971_07_SE_FM.indd 4 20/02/16 12:08 AM Organization e c T his book’s organization, sequencing, and pace of topic coverage make learning and teaching easier by n focusing your attention on one concept at a time, by providing flexibility in the order in which you can a cover topics, and by clearly distinguishing between the specification and implementation of abstract data l types, or ADTs. To accomplish these goals, we have organized the material into 21 chapters and G 8 interludes. Most chapters focus on either the specification and use of an ADT or its various implementations. You can choose to cover the specification of an ADT followed by its implementations, a or you can treat the specification and use of several ADTs before you consider any implementation issues. t The book’s organization makes it easy for you to choose the topic order that you prefer. a Contents at a Glance s t The following list shows the overall composition of the book. A further chapter-by-chapter description appears n later. Note that gray highlighted sections are available online. e Chapter 1 Data Abstraction: The Walls t C++ Interlude 1 C++ Classes n Chapter 2 Recursion: The Mirrors o Chapter 3 Array-Based Implementations C++ Interlude 2 Pointers, Polymorphism, and Memory Allocation C Chapter 4 Link-Based Implementations Chapter 5 Recursion as a Problem-Solving Technique Chapter 6 Stacks C++ Interlude 3 Exceptions Chapter 7 Implementations of the ADT Stack Chapter 8 Lists Chapter 9 List Implementations C++ Interlude 4 Safe Memory Management Using Smart Pointers Chapter 10 Algorithm Efficiency Chapter 11 Sorting Algorithms and Their Efficiency C++ Interlude 5 Class Relationships and Reuse Chapter 12 Sorted Lists and Their Implementations Chapter 13 Queues and Priority Queues Chapter 14 Queue and Priority Queue Implementations C++ Interlude 6 Overloaded Operators and Friend Access Chapter 15 Trees Chapter 16 Tree Implementations Chapter 17 Heaps C++ Interlude 7 Iterators Chapter 18 Dictionaries and Their Implementations Chapter 19 Balanced Search Trees Chapter 20 Graphs Chapter 21 Processing Data in External Storage C++ Interlude 8 The Standard Template Library Appendix A Review of C++ Fundamentals Appendix B Important Themes in Programming Appendix C The Unified Modeling Language Appendix D The Software Life Cycle Appendix E Mathematical Induction Appendix F Algorithm Verification Appendix G C++ File Fundamentals Appendix H C++ Header Files and Standard Functions Appendix I C++ Documentation Systems Appendix J ASCII Character Codes Appendix K C++ for Java Programmers Appendix L C++ for Python Programmers Index Glossary Answers to Checkpoint Questions v A01_CARR3971_07_SE_FM.indd 5 22/02/16 3:16 PM n What’s New? o T i his edition of Walls and Mirrors is an important enhancement of the previous edition, yet retains a peda- t gogical approach that makes the material accessible to students at the introductory level. The coverage that you i d enjoyed in previous editions is still here. As is usual for us, we have read every word of the previous edition and made changes to improve clarity and correctness. No chapter or interlude appears exactly as it did before. In E this new edition, we s • Updated the C++ code to follow professional conventions by using i h Exceptions rather than return values to signal unusual situations. Safe and secure coding techniques, such as those found in SEI CERT Coding Standards. T C++11 and C++14 features where applicable. Note that we tested the C++ code using the following compilers: GNU g++, clang/LLVM, Xcode 6.x, o and Visual Studio 2013 and 2015RC. t • Refined our terminology and presentation to ease understanding. w • Revised figures to improve clarity. e • Replaced technologically dated examples. N • Added Notes and Programming Tips. • Added programming problems in the areas of gaming, finance, and e-commerce. • Added Security Notes as a new element. • Added a new C++ Interlude 4, “Safe Memory Management Using Smart Pointers,” midway in the book to introduce smart pointers, a C++11 feature. Chapters subsequent to this interlude use smart pointers. vi A01_CARR3971_07_SE_FM.indd 6 20/02/16 12:08 AM Chapter-by-Chapter Overview n R o eaders of this book should have completed a programming course, preferably in C++. Appendix A covers i the essentials of C++ that we assume readers will know. You can use this Appendix as a review or as the basis for t p making the transition to C++ from another programming language. Note that Appendixes K and L offer some i help for those who are transitioning from Java or Python, respectively. r c • Chapters 1 through 5: Chapter 1 introduces object-oriented concepts and discusses problem solving, s good programming practices, and ADTs. It then specifies a simple ADT—the bag—and declares the e bag’s operations within a C++ template interface in a nonthreatening way. Such interfaces enable D the client to choose the type of data that the ADT stores. Next is C++ Interlude 1, which presents C++ classes. It gives more details about template t interfaces—like the one presented in Chapter 1—and shows how to use inheritance to define a class n derived from an interface. e As it did in earlier editions, Chapter 2 introduces recursion, and Chapter 5 develops it as a t problem-solving tool. Recursion is revisited often throughout the book. n We clearly separate the specification, use, and implementation of the bag by dividing the mate- o rial across several chapters. For example, Chapter 1 specifies the bag and provides several examples C of its use. Chapter 3 covers implementations that use arrays. Just before Chapter 4 introduces chains of linked nodes and uses one in the definition of a class of bags, C++ Interlude 2 covers pointers, d polymorphism, and dynamic memory allocation. Both Chapters 3 and 4 include recursion in their e presentation. l By introducing the bag as the first ADT we consider, we make the difficult topic of linked data i more accessible to students. Adding or removing the first node in a chain of linked nodes is the easi- a est task, and these simple manipulations are the ones we need to use for a linked implementation of t the bag. Subsequent chapters will add to this discussion of linked nodes. e Chapter 3 does more than simply implement the ADT bag. It shows how to approach the imple- D mentation of a class by initially focusing on core methods. When defining a class, it is often useful to implement and test these core methods first and to leave definitions of the other methods for later. Chapter 4 follows this approach in its development of a link-based implementation of the ADT bag. We continue to separate specification from implementation throughout most of the book when we discuss various other ADTs. You can choose to cover the chapters that specify and use the ADTs and then later cover the chapters that implement them. Or you can cover the chapters as they appear, implementing each ADT right after studying its specification and use. A list of chapter prerequisites appears later in this preface to help you plan your path through the book. • Chapters 6 and 7: Chapter 6 discusses stacks, giving examples of their use, and Chapter 7 implements the stack using an array and then again using a chain. We manipulate this chain in same way that we do for the ADT bag. Between these chapters is C++ Interlude 3, which discusses C++ exceptions. Chapter 7 then shows how to use an exception in the implementation of the ADT stack, when a cli- ent violates a method’s precondition. • Chapters 8 and 9: The next two chapters introduce the ADT list. We discuss this container abstractly and then implement it by using an array and then a chain of linked nodes. Adding and removing a node that lies between existing nodes of a chain is easier for students to grasp, now that they have experience with the implementations of the bag and stack. Once again, we use exceptions to enforce method preconditions. • C++ Interlude 4: This new interlude introduces smart pointers, a recent addition to C++. We use smart pointers in linked implementations in subsequent chapters. • Chapters 10 and 11: Chapter 10 introduces the complexity of algorithms, a topic that we integrate into future chapters. Chapter 11 discusses various sorting techniques and their relative complexities. We consider both iterative and recursive versions of these algorithms. vii A01_CARR3971_07_SE_FM.indd 7 20/02/16 12:08 AM n • Chapter 12: Chapter 12 introduces the sorted list, and looks at a linked implementation and its effi- o ciency. We then talk about the relationship between a list and a sorted list and show how to use the i list as a base class for the sorted list. Note that Chapter 12 is preceded by C++ Interlude 5 that dis- t cusses class relationships and the various ways a class can be reused. Chapter 12 puts that discussion p into immediate use. i • Chapters 13 and 14: Chapter 13 presents the ADTs queue and priority queue, along with some uses r c of these containers. In doing so, we give an example of simulation that uses both ADTs, and finally s summarize the difference between position-oriented and value-oriented ADTs. Chapter 14 imple- e ments the queue, and introduces tail pointers, circularly linked chains, and circular arrays. We offer D an implementation of a priority queue by using a sorted list, but note that a better approach will come later when we introduce the ADT heap. t • Chapters 15 through 17: Before we begin the next chapter, C++ Interlude 6 introduces overloaded n operators and friend access. We overload operators when we define classes of trees in this group of e chapters. Chapter 15 discusses trees—binary, binary search, and general—and their possible uses. t Chapter 16 considers implementations of these trees, and briefly introduces the tree sort. C++ n Interlude 7 presents iterators in the context of a list. Chapter 17 introduces the ADT heap and shows o how to implement it by using an array. We then use a heap to implement the priority queue and to C sort an array. • Chapter 18: This chapter covers the specification and use of the ADT dictionary. We look at imple- d mentations of the dictionary that use an array or a binary search tree. We then introduce hashing e and use it as a dictionary implementation. l • Chapter 19: Chapter 19 introduces balanced search trees. Included in this chapter are the AVL, 2-3, i 2-4, and red-black trees. These trees are considered as implementations of the ADT dictionary. a • Chapter 20: Next, we discuss graphs, suggest two ways to implement them, and look at several t applications. e • Chapter 21: This last chapter considers data storage in external direct access files. Merge sort is D modified to sort such data, and external hashing and B-tree indexes are used to search it. These searching algorithms are generalizations of the internal hashing schemes and 2-3 trees already devel- oped. Finally, C++ Interlude 8 ends the main presentation by discussing the containers and algo- rithms available in the C++ Standard Template Library (STL). • Appendixes A through L: The appendixes provide supplemental information. As we mentioned ear- lier, Appendix A reviews C++ up to but not including classes. Appendixes B, C, D, and F present important aspects of programming, the Unified Modeling Language (UML), the software life cycle, and algorithm verification. Appendix E covers mathematical induction, and Appendix G covers input and output with external files. Appendix H provides a list of C++ header files and standard functions, and Appendix I considers the javadoc commenting style and defines the tags that we use in this book. Appendix J is simply a chart of the ASCII character codes. Finally, Appendixes K and L are brief transition guides to C++ for those who know Java or Python, respectively. viii A01_CARR3971_07_SE_FM.indd 8 20/02/16 12:08 AM