100% found this document useful (1 vote)
35 views

Data Structures and Algorithms in C 4th Edition Adam Drozdek download

The document provides information about the 4th edition of 'Data Structures and Algorithms in C' by Adam Drozdek, including links for instant ebook downloads in various formats. It outlines the contents of the book, which covers topics such as object-oriented programming, complexity analysis, linked lists, stacks, queues, recursion, binary trees, and multiway trees. Additionally, it mentions copyright information and the publisher's rights regarding the content.

Uploaded by

sidurchoupi2
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
35 views

Data Structures and Algorithms in C 4th Edition Adam Drozdek download

The document provides information about the 4th edition of 'Data Structures and Algorithms in C' by Adam Drozdek, including links for instant ebook downloads in various formats. It outlines the contents of the book, which covers topics such as object-oriented programming, complexity analysis, linked lists, stacks, queues, recursion, binary trees, and multiway trees. Additionally, it mentions copyright information and the publisher's rights regarding the content.

Uploaded by

sidurchoupi2
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 83

Data Structures and Algorithms in C 4th Edition

Adam Drozdek download

https://ebookgate.com/product/data-structures-and-algorithms-
in-c-4th-edition-adam-drozdek/

Get Instant Ebook Downloads – Browse at https://ebookgate.com


Get Your Digital Files Instantly: PDF, ePub, MOBI and More
Quick Digital Downloads: PDF, ePub, MOBI and Other Formats

Data Structures and Algorithms in C 1st Edition Michael


Mcmillan

https://ebookgate.com/product/data-structures-and-algorithms-
in-c-1st-edition-michael-mcmillan/

Data Structures Algorithms And Applications In C 2nd


Edition Sartaj Sahni

https://ebookgate.com/product/data-structures-algorithms-and-
applications-in-c-2nd-edition-sartaj-sahni/

Data Structures and Algorithms Using C 1st Edition


Michael Mcmillan

https://ebookgate.com/product/data-structures-and-algorithms-
using-c-1st-edition-michael-mcmillan/

C Programming Data Structures 4th Edition E.


Balagurusamy

https://ebookgate.com/product/c-programming-data-structures-4th-
edition-e-balagurusamy/
Data Structures and Other Objects Using C 4th Edition
Michael Main

https://ebookgate.com/product/data-structures-and-other-objects-
using-c-4th-edition-michael-main/

Data structures and algorithms made easy in Java data


structure and algorithmic puzzles 2nd Edition Narasimha
Karumanchi

https://ebookgate.com/product/data-structures-and-algorithms-
made-easy-in-java-data-structure-and-algorithmic-puzzles-2nd-
edition-narasimha-karumanchi/

Data Clustering Algorithms and Applications 1st Edition


Charu C. Aggarwal

https://ebookgate.com/product/data-clustering-algorithms-and-
applications-1st-edition-charu-c-aggarwal/

Data Structures Using C 2nd Edition D. S. Malik

https://ebookgate.com/product/data-structures-using-c-2nd-
edition-d-s-malik/

C and Data Structures by Practice 1st Ed. Edition


Ramesh Vasappanavara

https://ebookgate.com/product/c-and-data-structures-by-
practice-1st-ed-edition-ramesh-vasappanavara/
Data Structures
and Algorithms
in C++

Fourth Edition

Adam Drozdek

Australia • Brazil • Japan • Korea • Mexico • Singapore • Spain • United Kingdom • United States

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
This is an electronic version of the print textbook. Due to electronic rights restrictions,
some third party content may be suppressed. Editorial review has deemed that any suppressed
content does not materially affect the overall learning experience. The publisher reserves the right
to remove content from this title at any time if subsequent rights restrictions require it. For
valuable information on pricing, previous editions, changes to current editions, and alternate
formats, please visit www.cengage.com/highered to search by ISBN#, author, title, or keyword for
materials in your areas of interest.

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Data Structures and © 2013 Cengage Learning
Algorithms in C++,
ALL RIGHTS RESERVED. No part of this work covered by the copyright herein
Fourth Edition
may be reproduced, transmitted, stored or used in any form or by any means
by Adam Drozdek graphic, electronic, or mechanical, including but not limited to photocopying,
Executive Editor: Marie Lee recording, scanning, digitizing, taping, Web distribution, information networks,
or information storage and retrieval systems, except as permitted under
Senior Product Manager:
Section 107 or 108 of the 1976 United States Copyright Act, without the prior
Alyssa Pratt
written permission of the publisher.
Associate Product Manager:
Stephanie Lorenz
For product information and technology assistance, contact us at
Content Project Manager: Cengage Learning Customer & Sales Support, www.cengage.com/support
Matthew Hutchinson For permission to use material from this text or product, submit all
Art Director: Cheryl Pearl requests online at www.cengage.com/permissions
Further permissions questions can be emailed to
Print Buyer: Julio Esperas
[email protected]
Compositor: PreMediaGlobal
Proofreader: Andrea Schein Library of Congress Control Number: 2012942244
Indexer: Sharon Hilgenberg ISBN-13: 978-1-133-60842-4
ISBN-10: 1-133-60842-6
Cengage Learning
20 Channel Center Street
Boston, MA 02210
USA
Cengage Learning is a leading provider of customized learning solutions with
office locations around the globe, including Singapore, the United Kingdom,
Australia, Mexico, Brazil and Japan. Locate your local office at:
www.cengage.com/global
Cengage Learning products are represented in Canada by Nelson Education, Ltd.
To learn more about Cengage Learning, visit www.cengage.com
Purchase any of our products at your local college store or at our preferred
online store www.cengagebrain.com

Some of the product names and company names used in this book have been used for identification purposes only
and may be trademarks or registered trademarks of their respective manufacturers and sellers.

Any fictional data related to persons or companies or URLs used throughout this book is intended for instructional
purposes only. At the time this book was printed, any such data was fictional and not belonging to any real persons or
companies.

Cengage Learning reserves the right to revise this publication and make changes from time to time in its content
without notice.

The programs in this book are for instructional purposes only. They have been tested with care, but are not guaranteed
for any particular intent beyond educational purposes. The author and the publisher do not offer any warranties or repre-
sentations, nor do they accept any liabilities with respect to the programs.

Printed in the United States of America


1 2 3 4 5 6 7 18 17 16 15 14 13 12
Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
To my daughters, Justyna and Kasia

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Contents

1 Object-Oriented Programming Using C++ 1


1.1 Abstract Data Types 1
1.2 Encapsulation 1
1.3 Inheritance 6
1.4 Pointers 9
1.4.1 Pointers and Arrays 12
1.4.2 Pointers and Copy Constructors 14
1.4.3 Pointers and Destructors 16
1.4.4 Pointers and Reference Variables 17
1.4.5 Pointers to Functions 20
1.5 Polymorphism 21
1.6 C++ and Object-Oriented Programming 23
1.7 The Standard Template Library 24
1.7.1 Containers 24
1.7.2 Iterators 25
1.7.3 Algorithms 25
1.7.4 Function Objects 26
1.8 Vectors in the Standard Template Library 28
1.9 Data Structures and Object-Oriented Programming 35
1.10 Case Study: Random Access File 35
1.11 Exercises   46
1.12 Programming Assignments   48
Bibliography   50

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
vi ■ Contents

2 Complexity Analysis 51
2.1 Computational and Asymptotic Complexity 51
2.2 Big-O Notation 52
2.3 Properties of Big-O Notation 54
2.4 Ω and Θ Notations 56
2.5 Possible Problems 57
2.6 Examples of Complexities 57
2.7 Finding Asymptotic Complexity: Examples 59
2.8 The Best, Average, and Worst Cases 61
2.9 Amortized Complexity 64
2.10 NP-Completeness 68
2.11 Exercises   71
Bibliography   74

3 Linked Lists 75
3.1 Singly Linked Lists 75
3.1.1 Insertion 81
3.1.2 Deletion 83
3.1.3 Search 89
3.2 Doubly Linked Lists 90
3.3 Circular Lists 94
3.4 Skip Lists 96
3.5 Self-Organizing Lists 101
3.6 Sparse Tables 106
3.7 Lists in the Standard Template Library 109
3.8 Concluding Remarks 113
3.9 Case Study: A Library 114
3.10 Exercises   125
3.11 Programming Assignments   127
Bibliography   130

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Contents ■ vii

4 Stacks and Queues 131


4.1 Stacks 131
4.2 Queues 139
4.3 Priority Queues 148
4.4 Stacks in the Standard Template Library 149
4.5 Queues in the Standard Template Library 149
4.6 Priority Queues in the Standard Template Library 151
4.7 Deques in the Standard Template Library 153
4.8 Case Study: Exiting a Maze 158
4.9 Exercises   165
4.10 Programming Assignments   166
Bibliography   168

5 Recursion 169
5.1 Recursive Definitions 169
5.2 Function Calls and Recursion Implementation 172
5.3 Anatomy of a Recursive Call 174
5.4 Tail Recursion 177
5.5 Nontail Recursion 178
5.6 Indirect Recursion 184
5.7 Nested Recursion 186
5.8 Excessive Recursion 186
5.9 Backtracking 190
5.10 Concluding Remarks 197
5.11 Case Study: A Recursive Descent Interpreter 198
5.12 Exercises   207
5.13 Programming Assignments   210
Bibliography   213

6 Binary Trees 214


6.1 Trees, Binary Trees, and Binary Search Trees 214
6.2 Implementing Binary Trees 219
6.3 Searching a Binary Search Tree 222
Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
viii ■ Contents

6.4 Tree Traversal 224


6.4.1 Breadth-First Traversal 225
6.4.2 Depth-First Traversal 226
6.4.3 Stackless Depth-First Traversal 233
6.5 Insertion 240
6.6 Deletion 243
6.6.1 Deletion by Merging 244
6.6.2 Deletion by Copying 246
6.7 Balancing a Tree 250
6.7.1 The DSW Algorithm 253
6.7.2 AVL Trees 256
6.8 Self-Adjusting Trees 261
6.8.1 Self-Restructuring Trees 262
6.8.2 Splaying 263
6.9 Heaps 268
6.9.1 Heaps as Priority Queues 270
6.9.2 Organizing Arrays as Heaps 271
6.10 Treaps 276
6.11 k-d Trees 280
6.12 Polish Notation and Expression Trees 286
6.12.1 Operations on Expression Trees 287
6.13 Case Study: Computing Word Frequencies 290
6.14 Exercises   298
6.15 Programming Assignments   302
Bibliography   306

7 Multiway Trees 309


7.1 The Family of B-Trees 310
7.1.1 B-Trees 311
7.1.2 B*-Trees 321
7.1.3 B+-Trees 323
7.1.4 Prefix B+-Trees 326
7.1.5 K‑d B-trees 327
7.1.6 Bit-Trees 334
7.1.7 R-Trees 336
7.1.8 2–4 Trees 337
7.1.9 Sets and Multisets in the Standard Template Library 353
7.1.10 Maps and Multimaps in the Standard Template Library 359

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Contents ■ ix

7.2 Tries 364


7.3 Concluding Remarks 373
7.4 Case Study: Spell Checker 373
7.5 Exercises   384
7.6 Programming Assignments   385
Bibliography   389

8 Graphs 391
8.1 Graph Representation 393
8.2 Graph Traversals 395
8.3 Shortest Paths 398
8.3.1 All-to-All Shortest Path Problem 405
8.4 Cycle Detection 408
8.4.1 Union-Find Problem 409
8.5 Spanning Trees 411
8.6 Connectivity 415
8.6.1 Connectivity in Undirected Graphs 415
8.6.2 Connectivity in Directed Graphs 418
8.7 Topological Sort 421
8.8 Networks 423
8.8.1 Maximum Flows 423
8.8.2 Maximum Flows of Minimum Cost 433
8.9 Matching 438
8.9.1 Stable Matching Problem 442
8.9.2 Assignment Problem 445
8.9.3 Matching in Nonbipartite Graphs 447
8.10 Eulerian and Hamiltonian Graphs 449
8.10.1 Eulerian Graphs 449
8.10.2 Hamiltonian Graphs 453
8.11 Graph Coloring 459
8.12 NP-Complete Problems in Graph Theory 462
8.12.1 The Clique Problem 462
8.12.2 The 3-Colorability Problem 463
8.12.3 The Vertex Cover Problem 465
8.12.4 The Hamiltonian Cycle Problem 466
8.13 Case Study: Distinct Representatives 467

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
x ■ Contents

8.14 Exercises   480
8.15 Programming Assignments   486
Bibliography   487

9 Sorting 491
9.1 Elementary Sorting Algorithms 492
9.1.1 Insertion Sort 492
9.1.2 Selection Sort 495
9.1.3 Bubble Sort 497
9.1.4 Comb Sort 500
9.2 Decision Trees 501
9.3 Efficient Sorting Algorithms 505
9.3.1 Shell Sort 505
9.3.2 Heap Sort 508
9.3.3 Quicksort 512
9.3.4 Mergesort 518
9.3.5 Radix Sort 521
9.3.6 Counting Sort 527
9.4 Sorting in the Standard Template Library 528
9.5 Concluding Remarks 532
9.6 Case Study: Adding Polynomials 534
9.7 Exercises   542
9.8 Programming Assignments   543
Bibliography   545

10 Hashing 548
10.1 Hash Functions 549
10.1.1 Division 549
10.1.2 Folding 549
10.1.3 Mid-Square Function 550
10.1.4 Extraction 550
10.1.5 Radix Transformation 551
10.1.6 Universal Hash Functions 551
10.2 Collision Resolution 551
10.2.1 Open Addressing 552
10.2.2 Chaining 558
10.2.3 Bucket Addressing 560
10.3 Deletion 561
Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Contents ■ xi

10.4 Perfect Hash Functions 562


10.4.1 Cichelli’s Method 563
10.4.2 The FHCD Algorithm 566
10.5 Rehashing 568
10.5.1 The Cuckoo Hashing 568
10.6 Hash Functions for Extendible Files 571
10.6.1 Extendible Hashing 571
10.6.2 Linear Hashing 574
10.7 Case Study: Hashing with Buckets 576
10.8 Exercises   586
10.9 Programming Assignments   587
Bibliography   588

11 Data Compression 590


11.1 Conditions for Data Compression 590
11.2 Huffman Coding 592
11.2.1 Adaptive Huffman Coding 601
11.3 Run-Length Encoding 606
11.4 Ziv-Lempel Code 607
11.5 Case Study: Huffman Method with Run-Length Encoding 610
11.6 Exercises   622
11.7 Programming Assignments   622
Bibliography   624

12 Memory Management 625


12.1 The Sequential-Fit Methods 626
12.2 The Nonsequential-Fit Methods 627
12.2.1 Buddy Systems 629
12.3 Garbage Collection 636
12.3.1 Mark-and-Sweep 637
12.3.2 Copying Methods 644
12.3.3 Incremental Garbage Collection 646
12.3.4 Generational Garbage Collection 653
12.4 Concluding Remarks 657
12.5 Case Study: An In-Place Garbage Collector 658

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
xii ■ Contents

12.6 Exercises   667
12.7 Programming Assignments   668
Bibliography   671

13 String Matching 674


13.1 Exact String Matching 674
13.1.1 Straightforward Algorithms 674
13.1.2 The Knuth-Morris-Pratt Algorithm 677
13.1.3 The Boyer-Moore Algorithm 685
13.1.4 Multiple Searches 695
13.1.5 Bit-Oriented Approach 697
13.1.6 Matching Sets of Words 700
13.1.7 Regular Expression Matching 707
13.1.8 Suffix Tries and Trees 711
13.1.9 Suffix Arrays 717
13.2 Approximate String Matching 719
13.2.1 String Similarity 720
13.2.2 String Matching with k Errors 726
13.3 Case Study: Longest Common Substring 729
13.4 Exercises   738
13.5 Programming Assignments   740
Bibliography   741

Appendixes
A Computing Big-O 743
A.1 Harmonic Series 743
A.2 Approximation of the Function lg(n!) 743
A.3 Big-O for Average Case of Quicksort 745
A.4 Average Path Length in a Random Binary Tree 747
A.5 The Number of Nodes in an AVL Tree 748
B Algorithms in the Standard Template Library 749
B.1 Standard Algorithms 749
C NP-Completeness 758
C.1 Cook’s Theorem 758

Index 771

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Preface

The study of data structures, a fundamental component of a computer science edu-


cation, serves as the foundation upon which many other computer science fields are
built. Some knowledge of data structures is a must for students who wish to do work
in design, implementation, testing, or maintenance of virtually any software system.
The scope and presentation of material in Data Structures and Algorithms in C++
provide students with the necessary knowledge to perform such work.
This book highlights three important aspects of data structures. First, a very
strong emphasis is placed on the connection between data structures and their al-
gorithms, including analyzing algorithms’ complexity. Second, data structures are
presented in an object-oriented setting in accordance with the current design and
implementation paradigm. In particular, the information-hiding principle to ad-
vance encapsulation and decomposition is stressed. Finally, an important compo-
nent of the book is data structure implementation, which leads to the choice of C++
as the programming language.
The C++ language, an object-oriented descendant of C, is widespread in indus-
try and academia as an excellent programming language. It is also useful and natural
for introducing data structures. Therefore, because of the wide use of C++ in applica-
tion programming and the object-oriented characteristics of the language, using C++
to teach a data structures and algorithms course, even on the introductory level, is well
justified.
This book provides the material for an introductory data structures course,
as well as for an advanced data structures and algorithms course. It also meets the
requirements for the following units specified in the Computer Science Curriculum
2008: DS/GraphsAndTrees, PF/DataStructures, PF/Recursion, PF/ObjectOriented,
AL/BasicAnalysis, AL/AlgorithmicStrategies, AL/FundamentalAlgorithms,
AL/ PversusNP, PL/DeclarationsAndTypes, PL/AbstractionMechanisms, PL/
ObjectOrientedProgramming.
Most chapters include a case study that illustrates a complete context in which
certain algorithms and data structures can be used. These case studies were chosen
from different areas of computer science such as interpreters, symbolic computation,
and file processing, to indicate the wide range of applications to which topics under
discussion may apply.

xiii
Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
xiv ■ Preface

Brief examples of C++ code are included throughout the book to illustrate the
practical importance of data structures. However, theoretical analysis is equally im-
portant, so presentations of algorithms are integrated with analyses of efficiency.
Great care is taken in the presentation of recursion because even advanced stu-
dents have problems with it. Experience has shown that recursion can be explained
best if the run-time stack is taken into consideration. Changes to the stack are shown
when tracing a recursive function not only in the chapter on recursion, but also in
other chapters. For example, a surprisingly short function for tree traversal may re-
main a mystery if work done by the system on the run-time stack is not included in
the ­explanation. Standing aloof from the system and retaining only a purely theoreti-
cal perspective when discussing data structures and algorithms are not necessarily
helpful.
The thrust of this book is data structures, and other topics are treated here
only as much as necessary to ensure a proper understanding of this subject. Algo-
rithms are discussed from the perspective of data structures, so the reader will not
find a comprehensive discussion of different kinds of algorithms and all the facets
that a full presentation of algorithms requires. However, as mentioned, recursion
is covered in depth. In addition, complexity analysis of algorithms is presented in
some detail.
Chapters 1 and 3–8 present a number of different data structures and the algo-
rithms that operate on them. The efficiency of each algorithm is analyzed, and im-
provements to the algorithm are suggested.
■ Chapter 1 presents the basic principles of object-oriented programming, an intro-
duction to dynamic memory allocation and the use of pointers, and a rudimentary
presentation of the Standard Template Library (STL).
■ Chapter 2 describes some methods used to assess the efficiency of algorithms.
■ Chapter 3 presents different types of linked lists with an emphasis on their imple-
mentation with pointers.
■ Chapter 4 presents stacks and queues and their applications.
■ Chapter 5 contains a detailed discussion of recursion. Different types of recursion
are discussed, and a recursive call is dissected.
■ Chapter 6 discusses binary trees, including implementation, traversal, and search.
Balanced trees are also included in this chapter.
■ Chapter 7 details more generalized trees such as tries, 2– 4 trees, and B-trees.
■ Chapter 8 presents graphs.
Chapters 9–13 show different applications of data structures introduced in the
previous chapters. They emphasize the data structure aspects of each topic under
consideration.
■ Chapter 9 analyzes sorting in detail, and several elementary and nonelementary
methods are presented.
■ Chapter 10 discusses hashing, one of the most important areas in searching. Various
techniques are presented with an emphasis on the utilization of data structures.
■ Chapter 11 discusses data compression algorithms and data structures.

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Preface ■ xv

■ Chapter 12 presents various techniques and data structures for memory


­management.
■ Chapter 13 discusses many algorithms for exact and approximate string matching.
■ Appendix A discusses in greater detail big-O notation, introduced in Chapter 2.
■ Appendix B presents standard algorithms in the Standard Template Library.
■ Appendix C gives a proof of Cook’s theorem and illustrates it with an extended
example.
Each chapter contains a discussion of the material illustrated with appropriate
diagrams and tables. Except for Chapter 2, all chapters include a case study, which
is an extended example using the features discussed in that chapter. All case stud-
ies have been tested using the Visual C++ compiler on a PC and the g++ compiler
under Unix except the von Koch snowflake, which runs on a PC under Visual C++.
At the end of each chapter is a set of exercises of varying degrees of difficulty. Except
for Chapter 2, all chapters also include programming assignments and an up-to-date
bibliography of relevant literature.
Chapters 1– 6 (excluding Sections 2.9-10, 3.4, 6.4.3, 6.7-8, and 6.10-11) contain
the core material that forms the basis of any data structures course. These chapters
should be studied in sequence. The remaining six chapters can be read in any or-
der. A one-­semester course could include Chapters 1– 6, 9, and Sections 10.1 and
10.2. The entire book could also be part of a two-semester sequence.

Teaching Tools

The following instructor support materials are available when this book is used
in a classroom setting. All instructor teaching tools are available for download at
login.cengage.com.
Electronic Solution’s Manual. The Solution’s Manual that accompanies this textbook
includes complete solutions to all text exercises.
Electronic Figure Files. All images from the text are available for use in classroom
presentations.
PowerPoint Presentations. PowerPoint slides accompany each chapter. Slides may be
used to guide classroom presentation, to make available for students for chapter review,
or to print as classroom handouts. Instructors are encouraged to customize the slides to
suit their course needs.

Student Resources

Source Code. The source code for the text example programs is available for down-
load at cengagebrain.com and via the author’s Web site at http://www.mathcs.duq.
edu/drozdek/DSinCpp.

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
xvi ■ Preface

Changes in the Fourth Edition

The new edition primarily extends the old edition by including material on new topics
that are currently not covered. The additions include
■ A section on treaps (6.10) and a section on k-d trees (6.11)
■ A section on k-d B-trees (7.1.5)
■ A discussion of two additional sorting methods (Sections 9.1.3.1, 9.3.6)
■ A new hashing technique (Section 10.5.1)
■ A section on generational garbage collection (12.3.4)
There are also many small modifications and additions throughout the book.

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Object-Oriented
Programming
Using C++
1
© Cengage Learning 2013

1.1 Abstract Data Types


Before a program is written, we should have a fairly good idea of how to accom-
plish the task being implemented by this program. Hence, an outline of the program
­containing its requirements should precede the coding process. The larger and more
complex the project, the more detailed the outline phase should be. The implemen-
tation details should be delayed to the later stages of the project. In particular, the
details of the particular data structures to be used in the implementation should not
be ­specified at the beginning.
From the start, it is important to specify each task in terms of input and output.
At the beginning stages, we should be more concerned with what the program should
do, not how it should or could be done. Behavior of the program is more important
than the gears of the mechanism accomplishing it. For example, if an item is needed
to accomplish some tasks, the item is specified in terms of operations performed on it
rather than in terms of its inner structure. These operations may act upon this item,
for example, modifying it, searching for some details in it, or storing something in
it. After these operations are precisely specified, the implementation of the program
may start. The implementation decides which data structure should be used to make
execution most efficient in terms of time and space. An item specified in terms of op-
erations is called an abstract data type. An abstract data type is not a part of a program,
because a program written in a programming language requires the definition of
a data structure, not just the operations on the data structure. However, an object-
oriented language (OOL) such as C++ has a direct link to abstract data types by im-
plementing them as a class.

1.2 Encapsulation
Object-oriented programming (OOP) revolves around the concept of an object.
­Objects, however, are created using a class definition. A class is a template in accor-
dance to which objects are created. A class is a piece of software that includes a data

1
Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
2 ■ Chapter 1 Object-Oriented Programming Using C++

specification and functions operating on these data and possibly on the data belong-
ing to other class instances. Functions defined in a class are called methods, member
functions, or function members, and variables used in a class are called data members
(more properly, they should be called datum members). This combining of the data
and related operations is called data encapsulation. An object is an instance of a class,
an entity created using a class definition.
In contradistinction to functions in languages that are not object-oriented, ob-
jects make the connection between data and member functions much tighter and
more meaningful. In languages that are not object-oriented, declarations of data and
definitions of functions can be interspersed through the entire program, and only
the program documentation indicates that there is a connection between them. In
OOLs, a connection is established right at the outset; in fact, the program is based
on this connection. An object is defined by related data and operations, and because
there may be many objects used in the same program, the objects communicate by
exchanging messages that reveal as little detail about their internal structure as neces-
sary for adequate communication. Structuring programs in terms of objects allows us
to accomplish several goals.
First, this strong coupling of data and operations can be used much better in
modeling a fragment of the world, which is emphasized especially by software engi-
neering. Not surprisingly, OOP has its roots in simulation; that is, in modeling real-
world events. The first OOL was called Simula, and it was developed in the 1960s
in Norway.
Second, objects allow for easier error finding because operations are localized to
the confines of their objects. Even if side effects occur, they are easier to trace.
Third, objects allow us to conceal certain details of their operations from other
objects so that these operations may not be adversely affected by other objects. This
is known as the information-hiding principle. In languages that are not object-ori-
ented, this principle can be found to some extent in the case of local variables, or
as in Pascal, in local functions or procedures, which can be used and accessed only
by the function defining them. This is, however, a very tight hiding or no hiding at
all. Sometimes we may need to use (again, as in Pascal) a function f 2 defined in f 1
outside of f 1, but we cannot. Sometimes we may need to access some data local to
f 1 without exactly knowing the structure of these data, but we cannot. Hence, some
modification is needed, and it is accomplished in OOLs.
An object in OOL is like a watch. As users, we are interested in what the hands
show, but not in the inner workings of the watch. We are aware that there are gears
and springs inside the watch, but because we usually know very little about why all
these parts are in a particular configuration, we should not have access to this mecha-
nism so that we do not damage it, inadvertently or on purpose. This mechanism is
hidden from us, we have no immediate access to it, and the watch is protected and
works better than when its mechanism is open for everyone to see.
An object is like a black box whose behavior is very well defined, and we use the
object because we know what it does, not because we have an insight into how it does
it. This opacity of objects is extremely useful for maintaining them independently of
each other. If communication channels between the objects are well defined, then
changes made inside an object can affect other objects only as much as these changes
affect the communication channels. Knowing the kind of information sent out and

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Section 1.2 Encapsulation ■ 3

received by an object, the object can be replaced more easily by another object more
suitable in a particular situation; a new object can perform the same task differently
but more quickly in a certain hardware environment. An object discloses only as
much as is needed for the user to utilize it. It has a public part that can be accessed by
any user when the user sends a message matching any of the member function names
revealed by the object. In this public part, the object displays to the user buttons that
can be pushed to invoke the object's operations. The user knows only the names of
these operations and the expected behavior.
Information hiding tends to blur the dividing line between data and operations.
In Pascal-like languages, the distinction between data and functions or procedures is
clear and rigid. They are defined differently and their roles are very distinct. OOLs
put data and methods together, and to the user of the object, this distinction is much
less noticeable. To some extent, this incorporates the features of functional lan-
guages. LISP, one of the earliest programming languages, allows the user to treat data
and functions similarly, because the structure of both is the same.
We have already made a distinction between particular objects and object types
or classes. We write functions to be used with different variables, and by analogy, we
do not like to be forced to write as many object declarations as the number of objects
required by the program. Certain objects are of the same type and we would like only
to use a reference to a general object specification. For single variables, we make a
distinction between type declaration and variable declaration. In the case of objects,
we have a class declaration and object instantiation. For instance, in the following
class declaration, C is a class and object1 through object3 are objects.
class C {
public:
C(char *s = "", int i = 0, double d = 1) {
strcpy(dataMember1,s);
dataMember2 = i;
dataMember3 = d;
}
void memberFunction1() {
cout << dataMember1 << ' ' << dataMember2 << ' '
<< dataMember3 << endl;
}
void memberFunction2(int i, char *s = "unknown") {
dataMember2 = i;
cout << i << " received from " << s << endl;
}
protected:
char dataMember1[20];
int dataMember2;
double dataMember3;
};

C object1("object1",100,2000), object2("object2"), object3;

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
4 ■ Chapter 1 Object-Oriented Programming Using C++

Message passing is equivalent to a function call in traditional languages. ­However,


to stress the fact that in OOLs the member functions are relative to ­objects, this new
term is used. For example, the call to public memberFunction1() in object1,
object1.memberFunction1();

is seen as message memberFunction1() sent to object1. Upon receiving the mes-


sage, the object invokes its member function and displays all relevant information.
Messages can include parameters so that
object1.memberFunction2(123);

is the message memberFunction2() with parameter 123 received by object1.


The lines containing these messages are either in the main program, in a func-
tion, or in a member function of another object. Therefore, the receiver of the mes-
sage is identifiable, but not necessarily the sender. If object1 receives the message
memberFunction1(), it does not know where the message originated. It only re-
sponds to it by displaying the information memberFunction1() encapsulates. The
same goes for memberFunction2(). Therefore, the sender may prefer sending a
message that also includes its identification, as follows:
object1.memberFunction2(123, "object1");

A powerful feature of C++ is the possibility of declaring generic classes by using


type parameters in the class declaration. For example, if we need to declare a class
that uses an array for storing some items, then we may declare this class as
class intClass {
int storage[50];
..................
};

However, in this way, we limit the usability of this class to integers only; if we
need a class that performs the same operations as intClass except that it operates
on float numbers, then a new declaration is needed, such as
class floatClass {
float storage[50];
..................
};

If storage is to hold structures, or pointers to characters, then two more classes


must be declared. It is much better to declare a generic class and decide what type of
items the object is referring to only when defining the object. Fortunately, C++ al-
lows us to declare a class in this way, and the declaration for the example is
template<class genType>
class genClass {
genType storage[50];
...................
};

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Section 1.2 Encapsulation ■ 5

Later, we make the decision about how to initialize genType:


genClass<int> intObject;
genClass<float> floatObject;

This generic class becomes a basis for generating two new classes, genClass
of int and genClass of float, and then these two classes are used to create two
­objects, intObject and floatObject. In this way, the generic class manifests it-
self in different forms depending on the specific declaration. One generic declaration
­suffices for enabling such different forms.
We can go even further than that by not committing ourselves to 50 cells in
storage and by delaying that decision until the object definition stage. But just in
case, we may leave a default value so that the class declaration is now
template<class genType, int size = 50>
class genClass {
genType storage[size];
..................
};

The object definition is now


genClass<int> intObject1; // use the default size;
genClass<int,100> intObject2;
genClass<float,123> floatObject;

This method of using generic types is not limited to classes only; we can use
them in function declarations as well. For example, the standard operation for swap-
ping two values can be defined by the function
template<class genType>
void swap(genType& el1, genType& el2) {
genType tmp = el1; el1 = el2; el2 = tmp;
}

This example also indicates the need for adapting built-in operators to spe-
cific situations. If genType is a number, a character, or a structure, then the as-
signment operator, =, performs its function properly. But if genType is an array,
then we can expect a problem in swap(). The problem can be resolved by over-
loading the assignment operator by adding to it the functionality required by a
specific data type.
After a generic function has been declared, a proper function can be generated at
compilation time. For example, if the compiler sees two calls,
swap(n,m); // swap two integers;
swap(x,y); // swap two floats;

it generates two swap functions to be used during execution of the program.

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
6 ■ Chapter 1 Object-Oriented Programming Using C++

1.3 Inheritance
OOLs allow for creating a hierarchy of classes so that objects do not have to be in-
stantiations of a single class. Before discussing the problem of inheritance, consider
the following class definitions:
class BaseClass {
public:
BaseClass() { }
void f(char *s = "unknown") {
cout << "Function f() in BaseClass called from " << s << endl;
h();
}
protected:
void g(char *s = "unknown") {
cout << "Function g() in BaseClass called from " << s << endl;
}
private:
void h() {
cout << "Function h() in BaseClass\n";
}
};
class Derived1Level1 : public virtual BaseClass {
public:
void f(char *s = "unknown") {
cout << "Function f() in Derived1Level1 called from " << s << endl;
g("Derived1Level1");
h("Derived1Level1");
}
void h(char *s = "unknown") {
cout << "Function h() in Derived1Level1 called from " << s << endl;
}
};
class Derived2Level1 : public virtual BaseClass {
public:
void f(char *s = "unknown") {
cout << "Function f() in Derived2Level1 called from " << s << endl;
g("Derived2Level1");
// h(); // error: BaseClass::h() is not accessible
}
};
class DerivedLevel2 : public Derived1Level1, public Derived2Level1 {
public:
void f(char *s = "unknown") {
cout << "Function f() in DerivedLevel2 called from " << s << endl;
g("DerivedLevel2");

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Section 1.3 Inheritance ■ 7

Derived1Level1::h("DerivedLevel2");
BaseClass::f("DerivedLevel2");
}
};
A sample program is
int main() {
BaseClass bc;
Derived1Level1 d1l1;
Derived2Level1 d2l1;
DerivedLevel2 dl2;
bc.f("main(1)");
// bc.g(); // error: BaseClass::g() is not accessible
// bc.h(); // error: BaseClass::h() is not accessible
d1l1.f("main(2)");
// d1l1.g(); // error: BaseClass::g() is not accessible
d1l1.h("main(3)");
d2l1.f("main(4)");
// d2l1.g(); // error: BaseClass::g() is not accessible
// d2l1.h(); // error: BaseClass::h() is not accessible
dl2.f("main(5)");
// dl2.g(); // error: BaseClass::g() is not accessible
dl2.h();
return 0;
}

This sample produces the following output:


Function f() in BaseClass called from main(1)
Function h() in BaseClass
Function f() in Derived1Level1 called from main(2)
Function g() in BaseClass called from Derived1Level1
Function h() in Derived1Level1 called from Derived1Level1
Function h() in Derived1Level1 called from main(3)
Function f() in Derived2Level1 called from main(4)
Function g() in BaseClass called from Derived2Level1
Function f() in DerivedLevel2 called from main(5)
Function g() in BaseClass called from DerivedLevel2
Function h() in Derived1Level1 called from DerivedLevel2
Function f() in BaseClass called from DerivedLevel2
Function h() in BaseClass
Function h() in Derived1Level1 called from unknown

The class BaseClass is called a base class or a superclass, and other classes are called
subclasses or derived classes because they are derived from the superclass in that they can
use the data members and member functions specified in BaseClass as protected or
public. They inherit all these members from their base class so that they do not have
to repeat the same definitions. However, a derived class can override the ­definition of a

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
8 ■ Chapter 1 Object-Oriented Programming Using C++

member function by introducing its own definition. In this way, both the base class and
the derived class have some measure of control over their member functions.
The base class can decide which member functions and data members can be re-
vealed to derived classes so that the principle of information hiding holds not only with
respect to the user of the base class, but also to the derived classes. Moreover, the derived
class can decide which parts of the public and protected member functions and data
members to retain and use and which to modify. For example, both ­Derived1Level1
and Derived2Level1 define their own versions of f(). However, the access to the
member function with the same name in any of the classes higher up in the hierarchy is
still possible by preceding the function with the name of the class and the scope opera-
tor, as shown in the call of BaseClass::f() from f() in DerivedLevel2.
A derived class can add some new members of its own. Such a class can become
a base class for other classes that can be derived from it so that the inheritance hierar-
chy can be deliberately extended. For example, the class Derived1Level1 is derived
from BaseClass, but at the same time, it is the base class for DerivedLevel2.
Inheritance in our examples is specified as public by using the word public
after the semicolon in the heading of the definition of a derived class. Public inheri-
tance means that public members of the base class are also public in the derived class,
and protected members are also protected. In the case of protected inheritance (with
the word protected in the heading of the definition), both public and protected
members of the base class become protected in the derived class. Finally, for private
inheritance, both public and protected members of the base class become private in
the derived class. In all types of inheritance, private members of the base class are
inaccessible to any of the derived classes. For example, an attempt to call h() from
f() in Derived2Level1 causes a compilation error, “BaseClass::h() is not ac-
cessible.” However, a call of h() from f() in Derived1Level1 causes no problem
because it is a call to h() defined in Derived1Level1.
Protected members of the base class are accessible only to derived classes
and not to nonderived classes. For this reason, both Derived1Level1 and
Derived2Level1 can call BaseClass's protected member function g(), but a call
to this function from main() is rendered illegal.
A derived class does not have to be limited to one base class only. It can be
derived from more than one base class. For example, DerivedLevel2 is defined
as a class derived from both Derived1Level1 and Derived2Level1, inheriting
in this way all the member functions of Derived1Level1 and Derived2Level1.
However, DerivedLevel2 also inherits the same member functions from Base-
Class twice because both classes used in the definition of DerivedLevel2
are derived from BaseClass. This is redundant at best, and at worst can
cause a ­c ompilation error, "member is ambiguous BaseClass::g() and
­B aseClass::g(). " To prevent this from happening, the definitions of the
two classes include the modifier virtual, which means that DerivedLevel2
­c ontains only one copy of each member function from BaseClass. A simi-
lar problem arises if f() in D ­ erivedLevel2 calls h() without the preceding
scope operator and class name, ­D erived1Level1::h(). It does not matter
that h() is private in BaseClass and inaccessible to DerivedLevel2 . An
error would be printed, "member is ambiguous Derived1Level1::h() and
­ aseClass::h()."
B

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Section 1.4 Pointers ■ 9

1.4 Pointers
Variables used in a program can be considered as boxes that are never empty; they
are filled with some content either by the programmer or, if uninitialized, by the op-
erating system. Such a variable has at least two attributes: the content or value and the
­location of the box or variable in computer memory. This content can be a number,
a character, or a compound item such as a structure or union. However, this content
can also be the location of another variable; variables with such contents are called
pointers. Pointers are usually auxiliary variables that allow us to access the values
of other variables indirectly. A pointer is analogous to a road sign that leads us to
a ­certain location or to a slip of paper on which an address has been jotted down.
They are variables leading to variables, humble auxiliaries that point to some other
­variables as the focus of attention.
For example, in the declaration
int i = 15, j, *p, *q;

i and j are numerical variables and p and q are pointers to numbers; the star in
front of p and q indicates their function. Assuming that the addresses of the variables
i, j, p, and q are 1080, 1082, 1084, and 1086, then after assigning 15 to i in the
declaration, the positions and values of the variables in computer memory are as in
Figure 1.1a.
Now, we could make the assignment p = i (or p = (int*) i if the compiler
does not accept it), but the variable p was created to store the address of an integer
variable, not its value. Therefore, the proper assignment is p = &i, where the am-
persand in front of i means that the address of i is meant and not its content. Figure
1.1b illustrates this situation. In Figure 1.1c, the arrow from p to i indicates that p is
a pointer that holds the address of i.
We have to be able to distinguish the value of p, which is an address, from the
value of the location whose address the pointer holds. For example, to assign 20 to
the variable pointed to by p, the assignment statement is
*p = 20;

The star (*) here is an indirection operator that forces the system to first retrieve
the contents of p, then access the location whose address has just been retrieved from
p, and only afterward, assign 20 to this location (Figure 1.1d). Figures 1.1e through
1.1n give more examples of assignment statements and how the values are stored in
computer memory.
In fact, pointers—like all variables—also have two attributes: a content and a lo-
cation. This location can be stored in another variable, which then becomes a pointer
to a pointer.
In Figure 1.1, addresses of variables were assigned to pointers. Pointers can, how-
ever, refer to anonymous locations that are accessible only through their ­addresses
and not—like variables—by their names. These locations must be set aside by the
memory manager, which is performed dynamically during the run of the program,
unlike for variables, whose locations are allocated at compilation time.

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
10 ■ Chapter 1 Object-Oriented Programming Using C++

Figure 1.1 Changes of values after assignments are made using pointer variables. Note that (b)
and (c) show the same situation, and so do (d) and (e), (g) and (h), (i) and (j), (k) and
(l), and (m) and (n).

i j p q
int i = 15, j,
15 ? ? ? (a)
*p, *q; 1080 1082 1084 1086
i j p q
p = &i; 15 ? 1080 ? (b)
1080 1082 1084 1086
p i
15 (c)
i j p q
*p = 20; 20 ? 1080 ? (d)
1080 1082 1084 1086
p i
20 (e)
i j p q
j = 2 * *p; 20 40 1080 ? (f)
1080 1082 1084 1086
i j p q
q = &i; 20 40 1080 1080 (g)
1080 1082 1084 1086
p i
20 (h)
q

i j p q
*p = *q – 1; 19 40 1080 1080 (i)
1080 1082 1084 1086
To dynamically allocate and deallocate memory, two functions are used. One
p as muchi space as needed to store an object whose
function, new, takes from memory
19
type follows new. For example, with the instruction (j)
q
p = new int;

the program requests enough space to store


i one
j integer,
p from q the memory manager,
and theq address
= &j; of the beginning of this
19 portion
40 of 1080
memory is stored in p.(k)
1082 Now the
values can be ­assigned to the memory1080
block pointed
1082 1084to by p1086
only indirectly through a
pointer, either pointer p or anypother pointer
i q that was assigned the address stored
in p with the assignment q = p. 19 (l)
If the space occupied by theq integer accessible
j from p is no longer needed, it can
be returned to the pool of free memory locations
40 managed by the operating system
by issuing the instruction
i j p q
delete p; 39 40 1080 1082 (m)
*p = *q – 1;
1080 1082 1084 1086
p i
Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
1080 1082 1084 1086
i j p q
q = &i; 20 40 S e c t i o n1080
1080 1 . 4 P o i n t e r s (g)■ 11
1080 1082 1084 1086
p i
20 (h)
Figure 1.1 (continued)
q

i j p q
*p = *q – 1; 19 40 1080 1080 (i)
1080 1082 1084 1086
p i
19 (j)
q

i j p q
q = &j; 19 40 1080 1082 (k)
1080 1082 1084 1086
p i
19 (l)
q j
40

i j p q
*p = *q – 1; 39 40 1080 1082 (m)
1080 1082 1084 1086
p i
39 (n)
q j
40

However, after executing this statement, the beginning addresses of the released
­memory block are still in p, although the block, as far as the program is concerned,
does not exist anymore. It is like treating an address of a house that has been demol-
ished as the address of the existing location. If we use this address to find someone,
the result can be easily foreseen. Similarly, if after issuing the delete statement we
do not erase the address from the pointer variable participating in deletion, the re-
sult is potentially dangerous, and we can crash the program when trying to access
non­existing locations, particularly for more complex objects than numerical values.
This is the dangling reference problem. To avoid this problem, an address has to be
assigned to a pointer; if it cannot be the address of any location, it should be a null
address, which is simply 0. After execution of the assignment
p = 0;

we may not say that p refers to null or points to null but that p becomes null or p is null.
Another problem associated with delete is the memory leak. Consider the follow-
ing two lines of code:
p = new int;
p = new int;

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
12 ■ Chapter 1 Object-Oriented Programming Using C++

After allocating one cell for an integer, the same pointer p is used to allocate another
cell. After the second assignment, the first cell becomes inaccessible and also unavail-
able for subsequent memory allocations for the duration of the program. The problem
is with not releasing with delete the memory accessible from p before the second
assignment is made. The code should be:
p = new int;
delete p;
p = new int;

Memory leaks can become a serious problem when a program uses more and
more memory without releasing it, eventually exhausting memory and leading to ab-
normal termination. This is especially important in programs that are executed for a
long time, such as programs in servers.

1.4.1 Pointers and Arrays


In the previous section, the pointer p refers to a block of memory that holds one inte-
ger. A more interesting situation is when a pointer refers to a data structure that is
created and modified dynamically. This is a situation where we would need to over-
come the restrictions imposed by arrays. Arrays in C++, and in most programming
languages, have to be declared in advance; therefore, their sizes have to be known
before the program starts. This means that the programmer needs a fair knowledge
of the problem being programmed to choose the right size for the array. If the size
is too big, then the array unnecessarily occupies memory space, which is basically
wasted. If the size is too small, the array can overflow with data and the program
will abort. Sometimes the size of the array simply cannot be predicted; therefore,
the decision is delayed until run time, and then enough memory is allocated to hold
the array.
The problem is solved with the use of pointers. Consider Figure 1.1b. In this fig-
ure, pointer p points to location 1080. But it also allows accessing of locations 1082,
1084, and so forth because the locations are evenly spaced. For example, to access the
value of variable j, which is a neighbor of i, it is enough to add the size of an integer
variable to the address of i stored in p to access the value of j, also from p. And this
is basically the way C++ handles arrays.
Consider the following declarations:
int a[5], *p;

The declarations specify that a is a pointer to a block of memory that can hold
five integers. The pointer a is fixed; that is, a should be treated as a constant so that
any attempt to assign a value to a, as in
a = p;

or in
a++;

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Section 1.4 Pointers ■ 13

is considered a compilation error. Because a is a pointer, pointer notation can be


used to access cells of the array a. For example, an array notation used in the loop
that adds all the numbers in a,
for (sum = a[0], i = 1; i < 5; i++)
sum += a[i];
can be replaced by a pointer notation
for (sum = *a, i = 1; i < 5; i++)
sum += *(a + i);
or by
for (sum = *a, p = a+1; p < a+5; p++)
sum += *p;
Note that a+1 is a location of the next cell of the array a so that a+1 is equivalent to
&a[1]. Thus, if a equals 1020, then a+1 is not 1021 but 1022 because pointer arith-
metic depends on the type of pointed entity. For example, after declarations
char b[5];
long c[5];
and assuming that b equals 1050 and c equals 1055, b+1 equals 1051 because one
character occupies 1 byte, and c+1 equals 1059 because one long number occupies
4 bytes. The reason for these results of pointer arithmetic is that the expression c+i
denotes the memory address c+i*sizeof(long).
In this discussion, the array a is declared statically by specifying in its declara-
tion that it contains five cells. The size of the array is fixed for the duration of the pro-
gram run. But arrays can also be declared dynamically. To that end, pointer variables
are used. For example, the assignment
p = new int[n];

allocates enough room to store n integers. Pointer p can be treated as an array vari-
able so that array notation can be used. For example, the sum of numbers in the array
p can be found with the code that uses array notation,

for (sum = p[0], i = 1; i < n; i++)


sum += p[i];

a pointer notation that is a direct rendition of the previous loop,


for (sum = *p, i = 1; i < n; i++)
sum += *(p+i);

or a pointer notation that uses two pointers,


for (sum = *p, q = p+1; q < p+n; q++)
sum += *q;

Because p is a variable, it can be assigned a new array. But if the array ­currently
pointed to by p is no longer needed, it should be disposed of by the ­instruction
delete [] p;

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
14 ■ Chapter 1 Object-Oriented Programming Using C++

Note the use of empty brackets in the instruction. The brackets indicate that p points
to an array. Also, delete should be used with pointers that were assigned a value
with new. For this reason, the two following applications of delete are very likely
to lead to a program crash:
int a[10], *p = a;
delete [] p;
int n = 10, *q = &n;
delete q;

A very important type of array is a string, or an array of characters. Many pre­


defined functions operate on strings. The names of these functions start with str, as
in strlen(s) to find the length of the string s or strcpy(s1,s2) to copy string
s2 to s1. It is important to remember that all these functions assume that strings
end with the null character '\0'. For example, strcpy(s1,s2) continues copying
until it finds this character in s2. If a programmer does not ­include this character in
s2, copying stops when the first occurrence of this character is found somewhere in
computer memory after location s2. This means that copying is performed to loca-
tions outside s1, which eventually may lead the ­program to crash.

1.4.2 Pointers and Copy Constructors


Some problems can arise when pointer data members are not handled properly when
copying data from one object to another. Consider the following definition:
struct Node {
char *name;
int age;
Node(char *n = "", int a = 0) {
name = strdup(n);
age = a;
}
};

The intention of the declarations


Node node1("Roger",20), node2(node1); //or node2 = node1;

is to create object node1, assign values to the two data members in node1, and then
create object node2 and initialize its data members to the same values as in node1.
These objects are to be independent entities so that assigning values to one of them
should not affect values in the other. However, after the assignments
strcpy(node2.name,"Wendy");
node2.age = 30;

the printing statement


cout<<node1.name<<' '<<node1.age<<' '<<node2.name<<' '<<node2.age;

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Section 1.4 Pointers ■ 15

Figure 1.2 Illustrating the necessity of using a copy constructor for objects with pointer
members.

node1 node1
name { R o g e r \0 W e n d y \0
age { 20 20
node2 node2
name {
age { 20 30
(a) (b)

node1 node1
R o g e r \0 R o g e r \0
20 20
node2 node2
R o g e r \0 W e n d y \0
20 30
(c) (d)

generates the output


Wendy 30 Wendy 20

The ages are different, but the names in the two objects are the same. What happened?
The problem is that the definition of Node does not provide a copy constructor
Node(const Node&);
which is necessary to execute the declaration node2(node1) to initialize node1.
If a user copy constructor is missing, the constructor is generated automatically by
the compiler. But the compiler-generated copy constructor performs member-by-
member copying. Because name is a pointer, the copy constructor copies the string
address node1.name to node2.name, not the string content, so that right after ex-
ecution of the declaration, the situation is as in Figure 1.2a. Now if the assignments
strcpy(node2.name,"Wendy");
node2.age = 30;

are executed, node2.age is properly updated, but the string "Roger" pointed to by
the name member of both objects is overwritten by "Wendy", which is also pointed
to by the two pointers (Figure 1.2b). To prevent this from happening, the user must
define a proper copy constructor, as in

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
16 ■ Chapter 1 Object-Oriented Programming Using C++

struct Node {
char *name;
int age;
Node(char *n = 0, int a = 0) {
name = strdup(n);
age = a;
}
Node(const Node& n) { // copy constructor;
name = strdup(n.name);
age = n.age;
}
};

With the new constructor, the declaration node2(node1) generates another copy
of "Roger" pointed to by node2.name (Figure 1.2c), and the assignments to data
members in one object have no effect on members in the other object, so that after
­execution of the assignments
strcpy(node2.name,"Wendy");
node2.age = 30;

the object node1 remains unchanged, as illustrated in Figure 1.2d.


Note that a similar problem is raised by the assignment operator. If a definition
of the assignment operator is not provided by the user, an assignment
node1 = node2;

performs member-by-member copying, which leads to the same problem as in Fig-


ure 1.2a–b. To avoid the problem, the assignment operator has to be overloaded by
the user. For Node, the overloading is accomplished by
Node& operator=(const Node& n) {
if (this != &n) { // no assignment to itself;
if (name != 0)
free(name);
name = strdup(n.name);
age = n.age;
}
return *this;
}

In this code, a special pointer this is used. Each object can access its own ad-
dress through the pointer this so that *this is the object itself.

1.4.3 Pointers and Destructors


What happens to locally defined objects of type Node? Like all local items, they are
destroyed in the sense that they become unavailable outside the block in which they
are defined, and memory occupied by them is also released. But although memory oc-
cupied by an object of type Node is released, not all the memory related to this ­object

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Section 1.4 Pointers ■ 17

becomes available. One of the data members of this object is a pointer to a string;
therefore, memory occupied by the pointer data member is released, but memory
taken by the string is not. After the object is destroyed, the string previously avail-
able from its data member name becomes inaccessible (if not assigned to the name of
some other object or to a string variable) and memory occupied by this string can no
longer be released, which leads to a memory leak. This is a problem with objects that
have data members pointing to dynamically allocated locations. To avoid the prob-
lem, the class definition should include a definition of a destructor. A destructor is a
function that is automatically invoked when an object is destroyed, which takes place
upon exit from the block in which the object is defined or upon the call of delete.
Destructors take no ­arguments and return no values so that there can be only one
destructor per class. For the class Node, a destructor can be defined as
~Node() {
if (name != 0)
free(name);
}

1.4.4 Pointers and Reference Variables


Consider the following declarations:
int n = 5, *p = &n, &r = n;

Variable p is declared as being of type int*, a pointer to an integer, and r is of type


int&, an integer reference variable. A reference variable must be initialized in its decla-
ration as a reference to a particular variable, and this reference cannot be changed. This
means that a reference variable cannot be null. A reference variable r can be consid-
ered a different name for a variable n so that if n changes then r changes as well. This is
­because a reference variable is implemented as a constant pointer to the variable.
After the three declarations, the printing statement
cout << n << ' ' << *p << ' ' << r << endl;
outputs 5 5 5. After the assignment
n = 7;

the same printing statement outputs 7 7 7. Also, an assignment


*p = 9;

gives the output 9 9 9, and the assignment


r = 10;

leads to the output 10 10 10. These statements indicate that in terms of notation, what
we can accomplish with dereferencing of pointer variables is accomplished without
dereferencing of reference variables. This is no accident because, as mentioned, refer-
ence variables are implemented as constant pointers. Instead of the declaration
int& r = n;

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
18 ■ Chapter 1 Object-Oriented Programming Using C++

we can use a declaration


int *const r = &n;

where r is a constant pointer to an integer, which means that the assignment


r = q;

where q is another pointer, is an error because the value of r cannot change. How-
ever, the assignment
*r = 1;

is acceptable if n is not a constant integer.


It is important to note the difference between the type int *const and the type
const int *. The latter is a type of pointer to a constant integer:

const int *s = &m;

after which the assignment


s = &m;

where m in an integer (whether constant or not) is admissible, but the assignment


*s = 2;

is erroneous, even if m is not a constant.


Reference variables are used in passing arguments by reference to function calls.
Passing by reference is required if an actual parameter should be changed perma-
nently during execution of a function. This can be accomplished with pointers (and
in C, this is the only mechanism available for passing by reference) or with reference
variables. For example, after declaring a function
void f1(int i, int* j, int& k) {
i = 1;
*j = 2;
k = 3;
}

the values of the variables


int n1 = 4, n2 = 5, n3 = 6;

after executing the call


f1(n1,&n2,n3);

are n1 = 4, n2 = 2, n3 = 3.
Reference type is also used in indicating the return type of functions. For ex-
ample, having defined the function
int& f2(int a[], int i) {
return a[i];
}

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Section 1.4 Pointers ■ 19

and declaring the array


int a[] = {1,2,3,4,5};

we can use f2() on any side of the assignment operator. For instance, on the right-
hand side,
n = f2(a,3);

or on the left-hand side,


f2(a,3) = 6;

which assigns 6 to a[3] so that a = [1 2 3 6 5]. Note that we can accomplish the same
with pointers, but dereferencing has to be used explicitly:
int* f3(int a[], int i) {
return &a[i];
}

and then
*f3(a,3) = 6;

Reference variables and the reference return type have to be used with caution
­ ecause there is a possibility of compromising the information-hiding principle
b
when they are used improperly. Consider class C:
class C {
public:
int& getRefN() {
return n;
}
int getN() {
return n;
}
private:
int n;
} c;

and these assignments:


int& k = c.getRefN();
k = 7;
cout << c.getN();

Although n is declared private, after the first assignment it can be accessed at will
from the outside through k and assigned any value. An assignment can also be made
through getRefN():
c.getRefN() = 9;

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
20 ■ Chapter 1 Object-Oriented Programming Using C++

1.4.5 Pointers to Functions


As indicated in Section 1.4.1, one of the attributes of a variable is its address indi-
cating its position in computer memory. The same is true for functions: One of the
­attributes of a function is the address indicating the location of the body of the func-
tion in memory. Upon a function call, the system transfers control to this location
to execute the function. For this reason, it is possible to use pointers to functions.
These pointers are very useful in implementing functionals (that is, functions that
take functions as arguments) such as an integral.
Consider a simple function:
double f(double x) {
return 2*x;
}

With this definition, f is the pointer to the function f(), *f is the function itself, and
(*f)(7) is a call to the function.
Consider now writing a C++ function that computes the following sum:

a f1i2
m

i5n

To compute the sum, we have to supply not only limits n and m, but also a func-
tion f. Therefore, the desired implementation should allow for passing numbers
not only as arguments, but also as functions. This is done in C++ in the following
­fashion:
double sum(double (*f)(double), int n, int m) {
double result = 0;
for (int i = n; i <= m; i++)
result += f(i);
return result;
}

In this definition of sum(), the declaration of the first formal argument


double (*f)(double)

means that f is a pointer to a function with one double argument and a double return
value. Note the need for parentheses around *f. Because parentheses have prece-
dence over the dereference operator *, the expression
double *f(double)

declares a function that returns a pointer to a double value.


The function sum() can be called now with any built-in or user-defined double
function that takes one double argument, as in
cout << sum(f,1,5) << endl;
cout << sum(sin,3,7) << endl;

Another example is a function that finds a root of a continuous function in an


interval. The root is found by repetitively bisecting an interval and finding a ­midpoint

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Section 1.5 Polymorphism ■ 21

of the current interval. If the function value at the midpoint is zero or the interval is
smaller than some small value, the midpoint is returned. If the values of the function
on the left limit of the current interval and on the midpoint have ­opposite signs, the
search continues in the left half of the current interval; otherwise, the current interval
becomes its right half. Here is an implementation of this algorithm:
double root(double (*f)(double), double a, double b, double epsilon) {
double middle = (a + b) / 2;
while (f(middle) != 0 && fabs(b - a) > epsilon) {
if (f(a) * f(middle) < 0) // if f(a) and f(middle) have
b = middle; // opposite signs;
else a = middle;
middle = (a + b) / 2;
}
return middle;
}

1.5 Polymorphism
Polymorphism refers to the ability of acquiring many forms. In the context of OOP
this means that the same function name denotes many functions that are members of
different objects. Consider the following example:
class Class1 {
public:
virtual void f() {
cout << "Function f() in Class1\n";
}
void g() {
cout << "Function g() in Class1\n";
}
};
class Class2 {
public:
virtual void f() {
cout << "Function f() in Class2\n";
}
void g() {
cout << "Function g() in Class2\n";
}
};
class Class3 {
public:
virtual void h() {
cout << "Function h() in Class3\n";
}
};

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
22 ■ Chapter 1 Object-Oriented Programming Using C++

int main() {
Class1 object1, *p;
Class2 object2;
Class3 object3;
p = &object1;
p->f();
p->g();
p = (Class1*) &object2;
p->f();
p->g();
p = (Class1*) &object3;
p->f(); // possibly abnormal program termination;
p->g();
// p->h(); // h() is not a member of Class1;
return 0;
}

The output of this program is as follows:


Function f() in Class1
Function g() in Class1
Function f() in Class2
Function g() in Class1
Function h() in Class3
Function g() in Class1

We should not be surprised that when p is declared as a pointer to object1 of


class type Class1, then the two function members are activated that are defined
in Class1. But after p becomes a pointer to object2 of class type Class2, then
p->f() activates a function defined in Class2, whereas p->g() activates a func-
tion defined in Class1. How is this possible? The difference lies in the moment at
which a decision is made about the function to be called.
In the case of the so-called static binding, the decision concerning a function to
be executed is determined at compilation time. In the case of dynamic binding, the de-
cision is delayed until run time. In C++, dynamic binding is enforced by declaring a
member function as virtual. In this way, if a virtual function ­member is called, then
the function chosen for execution depends not on the type of pointer determined by its
­declaration, but on the type of value the pointer ­currently has. In our example, pointer
p was declared to be of type Class1*. Therefore, if p points to function g() that is
not ­virtual, then regardless of the place in the program in which the call instruction
p‑>g()occurs, this is always con­sidered a call to the function g() defined in Class1.
This is due to the fact that the compiler makes this decision based on the type declara-
tion of p and the fact that g() is not ­virtual. For virtual function members the situ-
ation drastically changes. This time, the decision is made during run time: if a function
member is virtual, then the system looks at the type of the current pointer value and
­invokes the proper function member. After the initial declaration of p as being of type
Class1*, virtual function f() belonging to Class1 is called, whereas after assigning
to p the address of object2 of type Class2, f() belonging to Class2 is called.

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Section 1.6 C++ and Object-Oriented Programming ■ 23

Note that after p was assigned the address of object3, it still invokes g()de-
fined in Class1. This is because g() is not redefined in Class3 and g() from
Class1 is called. But an attempt to call p->f() results in a program crash—or gives
a wrong output since the C++ picks the first virtual function in Class3—because f()
is declared virtual in Class1 so the system tries to find, unsuccessfully, in Class3 a
definition of f(). Also, notwithstanding the fact that p points to object3, instruc-
tion p->h() results in a compilation error, because the compiler does not find h()
in Class1, where Class1* is still the type of pointer p. To the compiler, it does not
matter that h() is defined in Class3 (be it virtual or not).
Polymorphism is a powerful tool in OOP. It is enough to send a standard mes-
sage to many different objects without specifying how the message will be processed.
There is no need to know of what type the objects are. The receiver is responsible for
interpreting the message and following it. The sender does not have to modify the
­message depending on the type of receiver. There is no need for switch or if-else
statements. Also, new units can be added to a complex program without needing to
recompile the entire program.

1.6 C++ and Object-Oriented Programming

The previous discussion presumed that C++ is an OOL, and all the features of OOLs
that we discussed have been illustrated with C++ code. However, C++ is not a pure
OOL. C++ is more object-oriented than C or Pascal, which have no object-oriented
features, or Ada, which supports classes (packages) and instances; however, C++ is
less object-oriented than pure OOLs such as Smalltalk or Eiffel.
C++ does not enforce the object-oriented approach. We can program in C++
without knowing that such features are a part of the language. The reason for this is the
popularity of C. C++ is a superset of C, so a C programmer can easily switch to C++,
adapting only to its friendlier features such as I/O, call-by-reference mechanism, default
values for function parameters, operator overloading, inline functions, and the like. Us-
ing an OOL such as C++ does not guarantee that we are doing OOP. On the other hand,
invoking the entire machinery of classes and member functions may not always be nec-
essary, especially in small programs, so not enforcing OOP is not necessarily a disadvan-
tage. Also, C++ is easier to integrate with existing C code than other OOLs.
C++ has an excellent encapsulation facility that allows for well-controlled in-
formation hiding. There is, however, a relaxation to this rule in the use of so-called
friend functions. The problem is that private information of a certain class cannot
be ­accessed by anyone, and the public information is accessible to every user. But
sometimes we would like to allow only some users to have access to the private pool
of ­information. This can be accomplished if the class lists the user functions as its
friends. For example, if the definition is

class C {
int n;
friend int f();
} ob;

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
24 ■ Chapter 1 Object-Oriented Programming Using C++

function f() has direct access to variable n belonging to the class C, as in

int f ()
{ return 10 * ob.n; }

This could be considered a violation of the information-hiding principle; how-


ever, the class C itself grants the right to make public to some users what is private
and inaccessible to others. Thus, because the class has control over what to consider
a friend function, the friend function mechanism can be considered an extension of
the information-hiding principle. This mechanism, admittedly, is used to facilitate
programming and speed up execution, because rewriting code without using friend
functions can be a major problem. Such a relaxation of some rules is, by the way, not
uncommon in computer science; other examples include the existence of loops in
functional languages, such as LISP, or storing some information at the beginning of
data files in violation of the relational database model, as in dBaseIII+.

1.7 The Standard Template Library


C++ is an object-oriented language, but recent extensions to the language bring C++
to a higher level. The most significant addition to the language is the Standard Tem-
plate Library (STL), developed primarily by Alexander Stepanov and Meng Lee. The
library includes three types of generic entities: containers, iterators, and algorithms. Al-
gorithms are frequently used functions that can be applied to different data structures.
The application is mediated through the iterators that determine which algorithms can
be applied to which types of objects. The STL relieves programmers from writing their
own implementations of various classes and functions. Instead, they can use prepack-
aged generic implementations accommodated to the problem at hand.

1.7.1 Containers
A container is a data structure that holds some objects that are usually of the same type.
Different types of containers organize the objects within them differently. Although
the number of different organizations is theoretically unlimited, only a small number
of them have practical significance, and the most frequently used organizations are in-
corporated in the STL. The STL includes the following containers: deque, list, map,
­ ultimap, set, multiset, stack, queue, priority_queue, an­d vector.
m
The STL containers are implemented as template classes that include mem-
ber functions specifying what operations can be performed on the elements stored
in the data structure specified by the container or on the data structure itself. Some
operations can be found in all containers, although they may be implemented dif-
ferently. The member functions common to all containers include the default con-
structor, copy constructor, destructor, empty(), max_size(), size(), swap(),
operator=, and, except in priority_queue, six overloaded relational operator
functions ( operator<, etc.). Moreover, the member functions common to all
containers ­except stack, queue, and priority_queue include the functions be-
gin(), end(), rbegin(), rend(), erase(), and clear().

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Section 1.7 The Standard Template Library ■ 25

Elements stored in containers can be of any type, and they have to supply at least
a default constructor, a destructor, and an assignment operator. This is particularly
important for user-defined types. Some compilers may also require some relational
operators to be overloaded (at least operators == and <, but maybe != and > as well)
even though the program does not use them. Also, a copy constructor and the func-
tion operator = should be provided if data members are pointers because insertion
operations use a copy of an element being inserted, not the element itself.

1.7.2 Iterators
An iterator is an object used to reference an element stored in a container. Thus, it is
a generalization of the pointer. An iterator allows for accessing information included
in a container so that desired operations can be performed on these elements.
As a generalization of pointers, iterators retain the same dereferencing notation. For
example, *i is an element referenced by iterator i. Also, iterator arithmetic is similar to
pointer arithmetic, although all operations on iterators are not allowed in all containers.
No iterators are supported for the stack, queue, and ­priority_queue con-
tainers. Iterator operations for classes list, map, multimap, set, and multiset
are as follows (i1 and i2 are iterators, n is a number):
i1++, ++i1, i1--, --i1
i1 = i2
i1 == i2, i1 != i2
*i1

In addition to these operations, iterator operations for classes deque and


­ ector are as follows:
v

i1 < i2, i1 <= i2, i1 > i2, i1 >= i2


i1 + n, i1 - n
i1 += n, i1 -= n
i1[n]

1.7.3 Algorithms
The STL provides some 70 generic functions, called algorithms, that can be applied to
the STL containers and to arrays. A list of all the algorithms is in Appendix B. These
algorithms are implementing operations that are very frequently used in most pro-
grams, such as locating an element in a container, inserting an element into a sequence
of elements, removing an element from a sequence, modifying elements, comparing
elements, finding a value based on a sequence of elements, sorting the sequence of ele-
ments, and so on. Almost all STL algorithms use iterators to indicate the range of ele-
ments on which they operate. The first iterator references the first element of the range,
and the second iterator references an element after the last element of the range. There-
fore, it is assumed that it is always possible to reach the position indicated by the second
iterator by incrementing the first iterator. Here are some examples.
The call
random_shuffle(c.begin(), c.end());

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
26 ■ Chapter 1 Object-Oriented Programming Using C++

randomly reorders all the elements of the container c. The call


i3 = find(i1, i2, el);

returns an iterator indicating the position of element el in the range i1 up to, but
not including, i2. The call
n = count_if(i1, i2, oddNum);

counts with the algorithm count_if() the elements in the range indicated by itera-
tors i1 and i2 for which a one-argument user-defined Boolean function oddNum()
returns true.
Algorithms are functions that are in addition to the member functions provided
by containers. However, some algorithms are also defined as member functions to
provide better performance.

1.7.4 Function Objects


In C++, the function call operator () can be treated as any other operator; in particu-
lar, it can be overloaded. It can return any type and take any number of arguments, but
like the assignment operator, it can be overloaded only as a member function. Any ob-
ject that includes a definition of the function call operator is called a function object. A
function object is an object, but it behaves as though it were a function. When the func-
tion object is called, its arguments become the arguments of the function call operator.
Consider the example of finding the sum of numbers resulting from applying a
function f to integers in the interval [n, m]. An implementation sum() presented in Sec-
tion 1.4.5 relied on using a function pointer as an argument of function sum(). The same
can be accomplished by first defining a class that overloads the function call operator:
class classf {
public:
classf() {
}
double operator() (double x) {
return 2*x;
}
};
and defining
double sum2(classf f, int n, int m) {
double result = 0;
for (int i = n; i <= m; i++)
result += f(i);
return result;
}

which differs from sum() only in the first parameter, which is a function object, not
a function; otherwise, it is the same. The new function can now be called, as in
classf cf;
cout << sum2(cf,2,5) << endl;

Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Section 1.7 The Standard Template Library ■ 27

or simply
cout << sum2(classf(),2,5) << endl;
The latter way of calling requires a definition of constructor classf() (even if it has
no body) to create an object of type classf() when sum2() is called.
The same can be accomplished without overloading the function call operator,
as exemplified in these two definitions:
class classf2 {
public:
classf2 () {
}
double run (double x) {
return 2*x;
}
};
double sum3 (classf2 f, int n, int m) {
double result = 0;
for (int i = n; i <= m; i++)
result += f.run(i);
return result;
}
and a call
cout << sum3(classf2(),2,5) << endl;
The STL relies very heavily on function objects. The mechanism of function
pointers is insufficient for built-in operators. How could we pass a unary minus to
sum() ? The syntax sum(-,2,5) is illegal. To circumvent the problem, the STL
­defines function objects for the common C++ operators in <functional> . For
­example, unary minus is defined as
template<class T>
struct negate : public unary_function<T,T> {
T operator()(const T& x) const {
return -x;
}
};
Now, after redefining function sum() so that it becomes a generic function:
template<class F>
double sum(F f, int n, int m) {
double result = 0;
for (int i = n; i <= m; i++)
result += f(i);
return result;
}
the function can also be called with the negate function object:
sum(negate<double>(),2,5).
Copyright 2012 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Discovering Diverse Content Through
Random Scribd Documents
Purulent Bronchitis
It has been stated that a considerable number of cases of influenza developed a
more or less extensive purulent bronchitis. This term is used as descriptive of a
group of cases showing clinically evidence of a diffuse bronchitis as manifested by
numerous medium and fine moist râles scattered throughout the chest and
evidence of a definitely purulent inflammatory reaction as indicated by the
expectoration of fairly copious amounts of mucopurulent or frankly purulent
sputum. This condition is regarded as quite distinct, on the one hand, from the
common type of mucoid bronchitis frequently associated with “common colds” and
a fairly common feature of uncomplicated cases of influenza, in which physical
examination of the chest reveals only transient sibilant and musical râles without
evidence of extension to finer bronchi, and, on the other hand, from
bronchopneumonia.
Bacteriology.—Thirteen cases of purulent bronchitis following influenza in none
of which was there any evidence of pneumonia at the time cultures of the sputum
were made nor later were subjected to careful bacteriologic study. Specimens of
bronchial sputum were collected in sterile Petri dishes and selected portions
thoroughly washed to remove surface contaminations before bacteriologic
examinations were made. The results are shown in Table XIII.
Table XIII

Bacteriology of the Sputum in Cases of Purulent Bronchitis Following Influenza

DIRECT CULTURE ON MOUSE


CASE STAINED FILM OF SPUTUM
BLOOD AGAR PLATE INOCULATION

GJ B. influenzæ + + + B. influenzæ + + + + B. influenzæ


Pneumococcus
Gram + diplococci + Pneumococcus +
(type undetermined)
WAL B. influenzæ + + B. influenzæ + + +
Gram + diplococci + + Pneumococcus IV + +
TH B. influenzæ + + + B. influenzæ + + + +
Gram + diplococci + + + Pneumococcus IV + +
LH B. influenzæ + B. influenzæ + +
Gram + diplococci + Pneumococcus IV + +
FBD Gram + diplococci + + + + Pneumococcus IV + + + Pneumococcus IV
B. influenzæ + B. influenzæ
Wa B. influenzæ + + B. influenzæ + +
Gram + diplococci + + Pneumococcus IV + +
Sh B. influenzæ + + + B. influenzæ + +
Gram + diplococci + + Pneumococcus IV + + +
Wal Gram + diplostrep + + + S. viridans + +
B. influenzæ + B. influenzæ + +
CLF B. influenzæ + + + + + B. influenzæ
Gram + diplococci + Pneumococcus IV
NCC B. influenzæ + + B. influenzæ + + + B. influenzæ
Gram − micrococcus + M. catarrhalis + + M. catarrhalis
Gram + diplostrep. + S. viridans + +
JCM B. influenzæ + + + B. influenzæ + + + + B. influenzæ
Gram + streptococcus + S. hemolyticus + S. hemolyticus
Gram − micrococcus + M. catarrhalis + Pneumococcus IV
Gram + diplococcus +
Bl B. influenzæ + B. influenzæ
Gram + diplococcus + Pneumococcus IIa
Bu B. influenzæ + + + + B. influenzæ + + + B. influenzæ
Gram + diplococcus + + + + Pneumococcus IV + + + Pneumococcus IV
From the data presented in Table XIII it is evident that a mixed infection existed
in all cases. The results obtained by stained sputum films and by direct culture on
blood agar plates are of special significance. B. influenzæ was present in all cases,
being the predominant organism in 6 cases, abundantly present in others, and few
in number in 2. Of other organisms the pneumococcus was most frequently found,
occurring in 11 of the 13 cases, in all but 2 instances being present in considerable
numbers. S. viridans was encountered twice, once in association with a Gram-
negative micrococcus resembling M. catarrhalis culturally. S. hemolyticus was found
once, together with M. catarrhalis and a few pneumococci, Type IV, coming
through in the mouse only and of doubtful significance. The stained sputum films
and direct cultures always showed these organisms present in sufficient abundance
to indicate that they were present in the bronchial sputum and were not merely
contaminants from the buccal mucosa.
It seems quite probable from these results that purulent bronchitis following
influenza is, in most cases at least, due to mixed infection of the bronchi and
should be looked upon as a complication of influenza. Whether the condition may
be caused by infection with B. influenzæ alone is difficult to say. No evidence that it
may be caused by B. influenzæ alone was obtained in the cases studied. It is not
intended to enter here into a discussion as to whether B. influenzæ should be
regarded as a secondary invader or not; the other organisms encountered certainly
are. It would seem most probable that purulent bronchitis is caused by the mixed
infection of B. influenzæ and various other organisms, commonly the
pneumococcus, but that the condition is initiated by the invasion of the bronchi by
these other organisms in the presence of a preceding infection with B. influenzæ.
Clinical Features.—Purulent bronchitis following influenza began insidiously
without any prominent symptoms to mark its onset. About the third or fourth day
of influenza, when recovery from the primary disease might be looked for, the
patient would begin to cough more frequently, raising increasing amounts of
mucopurulent sputum. This sputum was yellowish green in color, copious in
amount, and often somewhat nummular in character, sometimes streaked with
blood. These symptoms were accompanied by the appearance of coarse, medium
and fine moist râles more or less diffusely scattered throughout the chest and
usually most numerous over the lower lobes. The percussion note, breath and
voice sounds, and vocal and tactile fremitus remained normal. There was no
increase in the respiratory rate or pulse rate, and cyanosis did not develop in the
absence of a beginning pneumonia. Many such cases, of course, developed
bronchopneumonia; in this event areas showing diminished resonance, suppressed
breath sounds, and fine crepitant râles with the “close to the ear” quality would
appear, the respiratory rate would become increased and cyanosis would become
evident. In those cases of purulent bronchitis not developing pneumonia, a
moderate elevation of temperature, rarely above 101° F., and irregular in character
usually occurred and persisted for a few days or a week.
Many cases maintained a persistent cough, raising considerable amounts of
sputum throughout the period of their convalescence in the hospital, which was
often considerably prolonged when this complication of influenza occurred.
Although no clinical data are available on such cases over a prolonged period of
observation, it seems probable that some of them, at least, had developed some
degree of bronchiectasis. This would seem all the more probable, since many cases
of pneumonia following influenza showed at autopsy extensive purulent bronchitis
with well-developed bronchiectasis. Bronchiectasis will be discussed in greater
detail in another section of this report. It is this group of cases with more or less
permanent damage to the bronchial tree that makes this type of bronchitis
following influenza a serious complication of the disease.
Pneumonia
The opportunity presented for a correlated study of the clinical features,
bacteriology, and pathology of pneumonia following influenza throughout the
period of the epidemic at Camp Pike from September 6, 1918, to December 15,
1918, made it evident that this pneumonia could be regarded as an entity in only
one respect, namely, that influenza was the predisposing cause. Clinically,
bacteriologically, and pathologically it presented a very diversified picture ranging
all the way from pneumococcus lobar pneumonia to hemolytic streptococcus
interstitial and suppurative pneumonia with the picture modified to a varying extent
by the preceding or concomitant influenzal infection.
One hundred and eleven consecutive cases in which careful clinical and
bacteriologic studies were made form the basis of the material presented. Of these
cases, 38 came to necropsy so that ample opportunity was presented to correlate
the clinical and bacteriologic studies made during life with the pathology and
bacteriology at necropsy. It has seemed advisable to group the cases primarily on
an etiologic basis with secondary division according to clinical features in so far as
this can be done. Bacteriologic studies showed that at the time of onset these
pneumonias were either pneumococcus pneumonias or mixed pneumococcus and
influenza bacillus pneumonias in nearly all instances. Certain of these cases later
became complicated by a superimposed hemolytic streptococcus or a
staphylococcus infection. In a few instances hemolytic streptococcus pneumonia
directly followed influenza without an intervening pneumococcus infection. B.
influenzæ was present in varying numbers in nearly all cases. In only 2 instances
however, was it found unassociated with pneumococci or hemolytic streptococci,
once alone and once with S. viridans.
Clinically the cases fell into four main groups: (1) Lobar pneumonia; (2) lobar
pneumonia with purulent bronchitis; (3) bronchopneumonia (pneumococcus); (4)
bronchopneumonia (streptococcus). It should be borne in mind, however, that the
picture was a complex one and that correct clinical interpretation was not always
possible, since many cases did not conform sharply to any one type and
superimposed infections during the course of the disease often modified the
picture.
Pneumococcus Pneumonia Following Influenza.—Bacteriologic
examination of selected and washed specimens of sputum coughed from the lungs
at time of onset of pneumonia showed the various immunologic types of
pneumococcus to be present in 105 cases. The incidence of the different types is
shown in Table XIV.
Table XIV

Types of Pneumococcus in 105 Cases of Pneumococcus Pneumonia Following Influenza

LOBAR PER
BRONCHOPNEUMONIA TOTAL
PNEUMONIA CENT
Pneumococcus, Type I 8 0 8 7.6
Pneumococcus, Type II 3 1 4 3.8
Pneumococcus, II atyp. 12 7 9 18.1
Pneumococcus, Type III 3 3 6 5.7
Pneumococcus, Group IV 32 36 68 64.8
The most noteworthy feature of the figures in Table XIV is the high proportion of
pneumonias due to types of pneumococci found in the mouths of normal
individuals, 93 cases or 88.6 per cent, being caused by Pneumococcus Types II
atypical, III, and IV. This is in harmony with the results generally reported and is in
all probability due to the fact that in patients with influenza pneumococci, which
under normal conditions would fail to cause pneumonia, readily gain access to the
respiratory tract and produce the disease. It is also of interest that with one
exception the highly parasitic pneumococci of Types I and II were associated with
pneumonias clinically lobar in type.
Superimposed infection of the lungs with other types of pneumococci than those
primarily responsible for the development of pneumonia occurred not infrequently
in this group of cases either during the course of the disease or shortly after
recovery from the first attack of pneumonia. Pneumococcus Type II infection was
superimposed upon or shortly followed pneumonia caused by Group IV
pneumococci in 4 instances, by Pneumococcus II atypical in 1 instance. In 1 case
pneumonia due to Pneumococcus II atypical occurred three days after recovery
from a Pneumococcus Type I pneumonia, in another case Pneumococcus Type III
infection was superimposed upon a pneumonia originally due to a pneumococcus
of Group IV. These cases are presented in detail in another section of this report,
and in several instances were shown to be directly due to contact infection from
patients in neighboring beds.
In a similar manner, superimposed infection with S. hemolyticus at some time
during the course of the pneumonia occurred in 13 cases in this group, with fatal
result in all but one. Streptococcus infection occurred in pneumonia due to
Pneumococcus II atypical once, to Pneumococcus Type III once, and to
pneumococci of Group IV eleven times. Nine of these cases were free from
hemolytic streptococci at the time of onset of the pneumonia, 4 showed a very few
colonies of hemolytic streptococci in the first sputum culture made.
B. influenzæ was found in the sputum coughed from the deeper air passages in
the majority of cases, being present in 80, or 76.2 per cent, of the 105 cases. In
the 58 cases of lobar pneumonia it was found 41 times, or 70.7 per cent, in the 47
cases of bronchopneumonia 39 times, or 82.9 per cent. The abundance of B.
influenzæ in the sputum varied greatly in different cases. Microscopic examination
of stained sputum films and direct culture of the sputum on blood agar plates
showed that in general it was more abundant in the mucopurulent sputum from
cases of bronchopneumonia than in the mucoid rusty sputum from cases of lobar
pneumonia. This was by no means an invariable rule, however, since in the former
the bacilli were sometimes very few in number, in the latter quite abundant.
Whether B. influenzæ shared in the production of the actual pneumonia in these
cases is difficult to decide and cannot be stated on the basis of the bacteriologic
and clinical observations which have been made.
Clinical Features.—One of the most striking aspects of pneumococcus
pneumonia following influenza was the diversity of clinical pictures presented.
These varied all the way from the classical picture of lobar pneumonia to that of
bronchopneumonia of all grades of severity from the rapidly fatal coalescing type to
that of very mild character with very slight signs of consolidation. For this reason it
is questioned whether there is any real justification for speaking of a typical
influenzal pneumonia, an opinion that seems well supported by the diversified
picture found at the necropsy table.
For purposes of presentation, pneumococcus pneumonia following influenza may
be divided into three clinical groups: (1) Lobar pneumonia; (2) lobar pneumonia
with purulent bronchitis; (3) bronchopneumonia. No accurate data are available as
to the relative frequency with which these three types occurred at Camp Pike. In
the group of 105 cases studied there were 58 cases of lobar pneumonia, 11 of
which had purulent bronchitis, and 47 cases of bronchopneumonia. The majority of
these cases, however, occurred during the early days of the epidemic of influenza
and probably show a considerably higher proportion of lobar pneumonias than
actually occurred in the total number of pneumonias throughout the epidemic. This
is indicated by the fact that of 100 consecutive cases of influenza selected for
observation at the height of the epidemic, 3 developed clinical evidence of lobar
pneumonia and 12 of bronchopneumonia.
(1) Lobar pneumonia presenting the typical clinical picture with sudden onset,
tenacious rusty sputum, sustained temperature, and physical signs of complete
consolidation of one or more lobes occurred in 47 cases; 36 cases in this group
definitely followed influenza. In 11 cases no certain clinical evidence of a preceding
influenza was obtained, and it is probable that some of these represent cases of
pneumonia occurring independently of the epidemic of influenza.
The onset of pneumonia in this group of cases occurred from four to nine days
after the onset of influenza and with few exceptions was ushered in by a chill and
pain in the chest. In several instances the patient had apparently recovered from
influenza as evidenced by fall of temperature to normal. After twenty-four to
seventy-two hours of normal temperature the patient would have a chill and
develop lobar pneumonia. In the majority of cases, however, lobar pneumonia
developed while the patient was still sick with influenza. The course of the disease,
symptomatology and physical signs were quite characteristic of lobar pneumonia
and require no special comment. Recovery by crisis occurred in 21 cases, by lysis in
8. Pneumococcus empyema developed in 3 cases, fibrinopurulent pericarditis in 3
and all but 1 of these 6 cases terminating fatally.
In Table XV 5 fatal cases of lobar pneumonia, which illustrate some of the
unusual features of the disease when it follows influenza, have been summarized.
The first 2 cases represent examples of recurring attacks of pneumonia which
developed shortly after recovery from the first attack, in both instances being due
to types of pneumococci different from those causing the first attack. The third
case represents an example of superimposed infection of the lungs with hemolytic
streptococci and staphylococci during the course of a pneumonia due to
Pneumococcus IV and disappearance of the latter organism from the tissues so
that it was not found at time of necropsy. The last 2 cases are examples of
fulminating rapidly fatal cases of lobar pneumonia associated with mixed infections
of pneumococci and hemolytic streptococci, the streptococci probably being
secondary in both cases. Cases like the few examples cited above, which occurred
not infrequently throughout the epidemic of influenza, serve to illustrate the
difficulties which may be met in attempting to correlate the clinical, bacteriologic
and pathologic features of pneumonia following influenza unless careful
bacteriologic examinations are made both during life and at the necropsy table in
the same group of cases.
Table XV

Cases of Lobar Pneumonia Following Influenza

CASE ONSET OF ONSET OF SPUTUM COURSE OF NECROPSY


INFLUENZA PNEUMONIA EXAMINATION PNEUMONIA
DATE BACTERIOLOGY DIAGNOSIS BACTERIOLOGY
Pul Sept. 7 Sept. 9 1st Sept. Pn. IV ++++ Recovery by crisis Lobar pneumonia. H.B. Pn. II
attack 10 B. inf. +++ on Sept. 14. On Gray hepatization Br. Pn. II ++++
bronchopn. Sept. 21 L.L, L.U, R.L. B. inf. +++
developed lobar R.L. Pn. II + +
pneumonia. Died
Sept. 30
Lew Sept. 16 Sept. 20 chill Sept. Pn. I +++ Lobar pn., Lobar pneumonia. H.B. Pn. II atyp.
22 B. inf. + recovery by crisis Gray hepatization Br. B. inf. ++++
Sept. 29. R.U. Pn. IIa +++
Developed 2nd Fibrinopurulent S. hem. +
attack lobar pn. on pleurisy Staph. +
Oct. 2. Died Oct. 8 R.U. Pn. IIa
++++
Col Sept. 20 Sept. 24 Sept. Pn. IV ++ Severe lobar Lobar pneumonia. H.B. S. hem.
27 pneumonia. Died Red hepatization all Br. S. hem.
on Sept. 30 lobes. ++++
Serofibrinous pl., Staph. +
rt. 125 c.c. L.L. S. hem.
++++
Staph. +
Gar Sept. 23 Sept. 28 Sept. Pn. IV ++ Fulminating rapidly Lobar pneumonia. H.B. S. hem.
30 S. hem. + fatal lobar Engorgement and Br. S. hem.
B. inf. + pneumonia. Died red hepatization ++++
Sept. 30 L.U., R.U. B. inf. +++
L.U. S. hem.
++++
Hol Sept. 25 Sept. 30 Sept. Pn. III ++ Fulminating rapidly Lobar pneumonia. H.B. sterile
30 B. inf. ++ fatal lobar Engorgement all Br. B. inf. ++++
pneumonia. Died lobes Pn. III ++
Oct. 1. S. hem. +
R.L. Pn. III
++++
B. inf. ++
S. hem. +
L.L. R.L., etc., indicates lobes involved. H. B. = Heart’s blood. Br. = bronchus.

(2) There were 11 cases of lobar pneumonia with purulent bronchitis in the
group studied. Clinically, they closely resembled the cases in the preceding group
except in so far as the picture was modified by the presence of the purulent
bronchitis. All directly followed influenza. The sputum, instead of being rusty and
tenacious, was profuse and mucopurulent, usually streaked with blood. Stained
films and direct culture on blood agar plates showed pneumococci in abundance
and B. influenzæ in varying numbers, in only two instances the predominant
organism. The physical signs were those of lobar pneumonia with, in addition,
those of a diffuse bronchitis as manifested by medium and coarse moist râles
throughout both chests. Five cases recovered by crisis; 6 terminated fatally and in
all of them the clinical diagnosis of lobar pneumonia with purulent bronchitis was
confirmed at necropsy.
(3) Forty-seven cases in the group studied presented the clinical picture of
bronchopneumonia. The onset of pneumonia in these cases was in most instances
insidious and appeared to occur as a continuation of the preceding influenza. The
temperature, instead of falling to normal after from three to four days, remained
elevated or rose higher, the respiratory rate began to rise, a moderate cyanosis
appeared, the cough increased, and the sputum became more profuse, usually
being mucopurulent and blood streaked, sometimes mucoid with fresh blood. The
pulse showed little change at first, being only moderately accelerated. Pleural pain,
so characteristic of the onset of lobar pneumonia, was rarely complained of, but a
certain amount of substernal pain was common, probably due to the severe
tracheobronchitis. Physical examination at this time revealed small areas showing
relative dullness, diminished or nearly absent breath sounds, and fine crepitant
râles. These areas usually appeared first posteriorly over the lower lobes.
The subsequent course of the disease showed the widest variation from mild
cases with limited pulmonary involvement going on to prompt recovery in four or
five days with defervescence by lysis or crisis to those presenting the picture of a
rapidly progressive and coalescing pneumonia with fatal outcome. In the milder
cases the diagnosis of pneumonia depended in considerable part upon the general
symptoms of continued fever, increased respiratory rate, and slight cyanosis.
Definite pulmonary signs were always present if carefully looked for, though
sometimes not outspoken. Areas of bronchial breathing and bronchophony often
appeared late, sometimes not until the patient was apparently recovering. In the
severe cases cyanosis became intense and an extreme toxemia dominated the
picture. In certain of these cases there was an intense pulmonary edema. The
respiratory rate showed wide variation, the breathing in some cases being rapid
and gasping, in others comparatively quiet. Progressive involvement of the lungs
occurred with the development of marked dullness, loud bronchial breathing and
bronchophony. Abundant medium and coarse moist râles were heard throughout
the chest, probably due in considerable part to the extensive bronchitis almost
universally present. An active delirium was not uncommon. Signs of pleural
involvement, even in the most severe and extensive cases, rarely occurred, except
in those cases in which a hemolytic streptococcus infection supervened.
Of the 47 cases in this group, 29 recovered; 14 by crisis, 15 by lysis. The average
duration of illness from the onset of influenza until recovery from the pneumonia
was ten days, the majority of these cases being relatively mild in character with
pneumonia of three to six days’ duration. Empyema with ultimate recovery
occurred in 1 of these cases, Pneumococcus Type II being the causative organism.
There were 18 fatal cases in the group. Nine of these are summarized in Table
XVI as illustrative of the frequently complex character of bronchopneumonia
following influenza and because of the interest attaching to the bacteriologic
examinations made during life and at necropsy. Case 70 is a typical instance of the
rapidly progressive type of confluent lobular pneumonia with extensive purulent
bronchitis, intense cyanosis, and appearance of suffocation, with which
pneumococci, in this case Pneumococcus IV, and B. influenzæ are commonly
associated. Case 59 is illustrative of the small group of bronchopneumonias
following influenza which die, often unexpectedly, after a long drawn out course, in
this instance three weeks after onset. Examination of the sputum at the time the
pneumonia began, showed Pneumococcus Type IV and B. influenzæ. At necropsy
there was a lobular pneumonia with clustered small abscesses, probably due to a
superimposed infection with S. aureus. There was a well-developed bronchiectasis
in the left lower lobe. Cultures taken at autopsy showed a sterile heart’s blood,
which is not infrequently the case in cases of pneumococcus lobular pneumonia
after influenza. Cultures from the consolidated portions of the lung showed no
growth, the pneumococcus having disappeared as might be expected from the
duration of the case. B. influenzæ together with staphylococci were found in the
bronchi. In Cases 50 and 56 a second attack of pneumonia caused by a different
type of pneumococcus from that responsible for the first attack occurred, the
second attack in both instances being due to contact infection with Pneumococcus
Type II from a patient in a neighboring bed suffering with Pneumococcus Type II
pneumonia. Both cases showed at necropsy the type of confluent lobular
pneumonia so commonly found in pneumococcus pneumonias following influenza.
Case 107 illustrates well the extent to which mixed infections may occur, especially
when cases are treated in crowded hospital wards. The sputum at time of onset
showed Pneumococcus IV in abundance and a few staphylococci. At necropsy there
was a confluent lobular pneumonia with clustered abscesses, purulent bronchitis,
and bronchiectasis in the left lower lobe. The heart’s blood was sterile, the lungs
showed Pneumococcus Type III and staphylococci. B. influenzæ was not found, but
through oversight, no cultures were taken from the bronchi. Cases 92, 99, 102, and
104 are all examples of superimposed hemolytic streptococcus infection occurring
in the presence of a Pneumococcus Type IV pneumonia, with the picture of
interstitial suppuration, abscess formation, and empyema due to S. hemolyticus on
the background of a pneumococcus lobular pneumonia found at necropsy. All
showed abundant pneumococci and B. influenzæ in the sputum and were free from
hemolytic streptococci at time of onset of pneumonia, except Case 92 which
showed 2 colonies of S. hemolyticus in the first sputum culture made. At time of
death the pneumococci had disappeared in all cases and were replaced by
hemolytic streptococci.
Table XVI

Cases of Bronchopneumonia Following Influenza

CASE ONSET OF ONSET OF SPUTUM COURSE OF NECROPSY


INFLUENZA PNEUMONIA EXAMINATION PNEUMONIA
DATE BACTERIOLOGY DIAGNOSIS BACTERIOLOGY
70 Sept. 18 Sept. 21 Sept. B. inf. ++++ Diffuse bronchitis Nodular and diffuse H.B. sterile
22 Pn. IV ++ with rapidly confluent lobular Br. B. inf. ++++
progressive pneumonia. Pn. IV ++
confluent Purulent bronchitis. Lun. B.inf. +++
bronchopneumonia. Bronchiectasis Pn. IV +++
Died Sept. 24
59 Sept. 13 Sept. 18 Sept. Pn. IV +++ Bronchopneumonia Lobular pneumonia, H.B. sterile
19 B. inf. + with long drawn with clustered Br. B.inf. +++
out course. Died abscesses. Staph. ++
Oct. 4 Bronchiectasis R.L. no growth.
50 Sept. 14 Sept. 17 Sept. Pn. IV +++ Mild Nodular and H.B. sterile
18 bronchopneumonia confluent lobular Br. B.inf. +++
improving on Sept. pneumonia. Staph +
24. On Sept. 26 Purulent bronchitis R.L. Pn. II +++
became suddenly B.inf. +
worse and died on L.U. Pn. II +++
Sept. 30
56 Sept. 10 Sept. 17 Sept. Pn. IIa +++ Bronchopneumonia Confluent lobular H.B. Pn. II
18 with recovery by pneumonia Br. Pn. II +++
crisis on Sept. 19. B.inf. ++
Developed a L.L. Pn. II +++
second attack of B.inf. +
pneumonia and
died Sept. 29
107 Sept. 27 Sept. 29 Oct. 1 Pn. IV +++ Diffuse bronchitis Confluent lobular H.B. sterile
B. inf. + and severe pneumonia with R.L. Pn. III ++
Staph. + bronchopneumonia. clustered Staph. ++
Died Oct. 5 abscesses. Pur. L.L. Staph. ++
bronchitis and
bronchiectasis
92 Sept. 23 Sept. 28 Oct. 1 B. inf. +++++ Severe Lobular pneumonia. H.B. S.hem.
Pn. IV +++ bronchopneumonia Empyema. Purulent Br. B.inf. +++
S. hem. 2 col. with empyema. bronchitis S.hem. +++
Died Oct. 5 R.L. S.hem. +++
B.inf. ++ Emp.
S.hem.
99 Sept. 24 Sept. 29 Oct. 1 B. inf. ++++ Diffuse purulent Bronchopneumonia. H.B. S.hem.
Pn. IV ++ bronchitis with Purulent bronchitis Br. B.inf. +++
S. vir. + bronchopneumonia. Lun. S.hem. +++
Died Oct. 7 S.hem. ++ B. inf.
+
102 Sept. 24 Sept. 28 Oct. 1 Pn. IIa +++ Severe Lobular pneumonia H.B. S.hem.
B. inf. ++ bronchopneumonia with interstitial Br. B.inf. +++
with empyema. suppuration. Pur. S.hem. +++
Died Oct. 4 bronchitis. R.L. S.hem. +++
Empyema
104 Sept. 26 Oct. 1 Oct. 1 B. inf. ++++ Diffuse purulent Nodular H.B. S.hem.
Pn. IV +++ bronchitis with bronchopneumonia R.L. S.hem.
severe with interstitial ++++
bronchopneumonia. suppuration. Pur. Emp S.hem.
Developed bronchitis and
streptococcus bronchiectasis.
empyema. Died Empyema.
Oct. 11
The cases cited in the preceding paragraph are illustrative examples from a
series of over 250 necropsies which are described in another section of this report.
They serve to indicate clearly the extent to which mixed and superimposed
infections of the lungs may occur in pneumonia following influenza and leave little
doubt that a considerable proportion of the deaths from influenzal pneumonia are
due to this circumstance.
Hemolytic Streptococcus Pneumonia Following
Influenza
But 4 cases of hemolytic streptococcus pneumonia directly following influenza
without an intervening pneumococcus infection of the lungs occurred in the group
of cases studied clinically. Superimposed infection with S. hemolyticus, however,
occurred not infrequently during the course of pneumococcus pneumonia following
influenza, as has been stated above. This occurred 3 times in lobar pneumonia and
10 times in bronchopneumonia, with fatal outcome in all but 1 case.
Bacteriology.—Bacteriologic examination of the sputum in the 4 cases of
streptococcus pneumonia directly following influenza showed S. hemolyticus
present in abundance. B. influenzæ was also present in large numbers in 3 cases,
but was not found in the fourth. In 1 case a Gram-negative micrococcus resembling
M. catarrhalis was also present in large numbers in the sputum. Pneumococci were
not found either by direct culture on blood agar plates or by inoculation of the
sputum intraperitoneally in white mice.
In the 13 cases of superimposed hemolytic streptococcus infection occurring
during the course of pneumococcus pneumonia, bacteriologic examination of the
sputum by direct culture and by mouse inoculation shortly after onset of the
pneumonia showed Pneumococci (atypical II once, Type III once, Group IV eleven
times) B. influenzæ present in large numbers, and no hemolytic streptococci except
in 4 instances in which a very few organisms were present. Subsequent invasion of
the lower respiratory tract by S. hemolyticus was shown to occur by means of
cultures of empyema fluids or by cultures made at necropsy.
Clinical Features.—The 4 cases of hemolytic streptococcus pneumonia
following influenza that occurred in this series resembled in all respects the
secondary streptococcus pneumonias of the winter and spring of 1918 and
presented no features requiring special comment. The onset resembled that of
pneumococcus bronchopneumonia, the disease appearing to develop as a
continuation of the preceding influenza. The sputum was profuse and
mucopurulent in 3 cases, mucoid and bloody in the other. Two cases ran a severe
and rapid course with the development of empyema early in the disease and fatal
outcome. The other 2 cases ran only moderately severe courses without developing
empyema and recovered by lysis in twenty and fifteen days, respectively, after the
onset of influenza. Clinical differentiation between streptococcus and
pneumococcus bronchopneumonia following influenza did not seem possible
without bacteriologic examination of the sputum except in those cases of the
streptococcus group which developed an extensive pleural effusion early in the
disease.
The advent of superimposed hemolytic streptococcus infection of the lower
respiratory tract during the course of pneumococcus pneumonia following influenza
presented no clinical features that made diagnosis certain without bacteriologic
examination. The sudden occurrence of a pleural exudate during the course of the
disease seemed of particular significance, especially since empyema in the
bronchopneumonias following influenza was exceedingly rare in the absence of
hemolytic streptococcus infection. Other suggestive symptoms were a chill during
the course of the disease, a sudden turn for the worse in cases apparently doing
well, or the development of a cherry red cyanosis. None of these features,
however, was sufficiently constant or distinctive of streptococcus invasion to be
depended upon and when they occurred, were merely indications for further
bacteriologic examination.
Bacillus Influenzæ Pneumonia Following Influenza
Bacteriologic evidence that cases of pneumonia following influenza might be due
to B. influenzæ alone was very meager in the group of cases studied clinically at
Camp Pike; in fact, no convincing evidence was obtained that such cases occurred.
In one case B. influenzæ alone was found in the sputum coughed from the deeper
air passages, and in another case B. influenzæ with a few colonies of S. viridans
was found. Both were cases of bronchopneumonia, mild in character, and
recovered promptly. They presented no clinical features by which they could be
distinguished from cases of pneumococcus bronchopneumonia.
It has been previously stated that B. influenzæ was found in all early
uncomplicated cases of influenza somewhere in the respiratory tract; that it was
present together with other organisms, notably pneumococcus in the sputum from
cases of purulent bronchitis following influenza; and that it was found in the
sputum coughed from the lung in approximately 80 per cent of cases of pneumonia
complicating influenza. In 35 cases it was very abundant, often being the
predominating organism. In all these cases, however, pneumococci or hemolytic
streptococci were also present in considerable numbers at the time of onset of the
pneumonia. It is impossible to say merely from the clinical and bacteriologic data
under consideration what part B. influenzæ played in the development of the actual
pneumonia in these cases. Discussion of this subject is therefore reserved for the
section of this report dealing with the pathology and bacteriology of pneumonia
following influenza.
Summary
Influenza as observed at Camp Pike presented itself as a highly contagious
infectious disease, the principal clinical manifestations of which were, sudden onset
with high fever, profound prostration with severe aching pains in the head, back
and extremities, erythema of the face, neck and upper chest with injection of the
conjunctivæ, and a rapidly progressive attack upon the mucous membranes of the
respiratory tract as evidenced by coryza, pharyngitis, tracheitis and bronchitis with
their accompanying symptoms. In the majority of cases it ran a short self-limited
course, rarely of more than four days’ duration, and was never fatal in the absence
of a complicating pneumonia.
Bacteriologic examination in early uncomplicated cases of the disease showed
the B. influenzæ of Pfeiffer to be present in all cases, often in predominating
numbers. It was found more abundantly present during the acute stage of the
disease than during convalescence in uncomplicated cases. No other organisms of
significance were encountered by the methods employed.
Purulent bronchitis of varying extent developed in approximately 35 per cent of
the cases and often prolonged the course of the illness to a considerable extent.
Bacteriologic studies showed that it was invariably associated with a mixed
infection of the bronchi with B. influenzæ and other bacteria, in most instances the
pneumococcus, and indicated that it should be regarded as a complication rather
than as an essential part of influenza. Its clinical features consisted of a mild febrile
reaction, frequent cough with the raising of considerable amounts of purulent
sputum, and the physical signs of a more or less diffuse bronchitis. It led to a
varying degree of bronchiectasis in at least some instances.
Pneumonia complicating influenza presented a very diversified picture and
appeared to have only one constant character, namely, that influenza was the
predisposing cause. It may be best classified on an etiologic basis since the clinical
features to some extent and the pathology to a much greater extent depended
upon the infecting bacteria in a given case.
Bacteriologic examination showed that a very large proportion of the cases was
due to infection with the different immunologic types of pneumococci or to a mixed
infection with B. influenzæ and pneumococci. The types of pneumococci commonly
found in normal mouths, namely, II atypical, III, and IV, comprised approximately
88 per cent of these, the highly parasitic Pneumococci Types I and II, but 12 per
cent. A small number of cases were due to hemolytic streptococci or to mixed
infection with B. influenzæ and S. hemolyticus. No certain evidence was obtained
that pneumonia was due to B. influenzæ alone. This organism was present in
varying numbers, however, in approximately 80 per cent of the sputums examined,
and it seems fairly certain that it must have played at least a part in the
development of the pneumonia in many of the cases in which it was found.
Superimposed infections with other types of pneumococci than those primarily
responsible for the development of pneumonia, with hemolytic streptococci and
with Staphylococcus aureus occurred frequently in cases of pneumococcus or
mixed pneumococcus and B. influenzæ pneumonia and undoubtedly contributed to
a considerable extent in increasing the number of deaths.
Three clinical types of pneumococcus pneumonia following influenza occurred:
lobar pneumonia, lobar pneumonia with purulent bronchitis, and
bronchopneumonia. Lobar pneumonia was usually sudden in onset and ran the
characteristic course of the primary disease. Lobar pneumonia with purulent
bronchitis similarly ran the characteristic course of the primary disease but
presented the unusual picture of lobar pneumonia with mucopurulent rather than
rusty, tenacious sputum and numerous moist râles throughout the unconsolidated
portions of the lungs. The cases of bronchopneumonia ran a very variable course
from mild cases of a few days’ duration and meager signs of consolidation to
rapidly progressive cases with signs of extensive pulmonary involvement. Purulent
bronchitis was very frequently associated with bronchopneumonia.
Hemolytic streptococcus pneumonia following influenza presented the clinical
picture of bronchopneumonia and was not readily distinguished on clinical grounds
from pneumococcus bronchopneumonia except in those cases which developed a
pleural exudate early in the disease. The advent of tertiary infection of the lower
respiratory tract with hemolytic streptococci in cases of secondary pneumococcus
pneumonia presented no symptoms sufficiently constant or certain to make clinical
diagnosis easy. The development of empyema in pneumococcus
bronchopneumonia usually meant streptococcus infection.
Pure B. influenzæ pneumonia, if such cases existed, presented no diagnostic
features by which it could be distinguished from pneumococcus bronchopneumonia
following influenza. It was impossible to determine on clinical and bacteriologic
grounds alone what part the prevalent influenza bacilli played in the causation of
the actual pneumonia.
Discussion
That wide variations in the conception of influenza have arisen during the recent
pandemic, even a hasty review of the literature makes clear. In its essence this
divergence of opinion seems to depend upon whether pneumonia is considered an
essential part of influenza or a complication due either to the primary cause of
influenza or to secondary infection. One extreme is expressed by Dunn[30] who says
“the so-called complication is the disease,” the other by Fantus[31] who finds
influenza a relatively mild disease with pneumonia a relatively infrequent and
largely preventable complication.
A similar divergence of opinion prevails with respect to the bacteriology of
influenza. There is fairly general agreement that the members of the
pneumococcus and streptococcus groups and to a less extent other organisms are
responsible for a large proportion of the secondary pneumonias, and but few
observers hold that they possess any etiologic relationship to influenza. No such
uniformity of opinion exists, however, with respect to the relation of B. influenzæ to
influenza and to the complicating pneumonia. By some it is considered the primary
cause of influenza, by others it is regarded as a secondary invader responsible for a
certain proportion of the secondary pneumonias, and by still others it is not
considered to bear any relation either to influenza or its complications.
A limited number of references to the extensive literature of the recent pandemic
will amply serve to illustrate the various points of view that have developed.
Keegan[32] regards pneumonia as a complication and considers that B. influenzæ,
the probable cause of influenza, is the primary cause of the pneumonia which may
or may not be still further complicated by pneumococcus or streptococcus infection
as a terminal event. Christian[33] states that epidemic influenza causes a clinically
demonstrable bronchitis and bronchopneumonia in the larger proportion of cases,
and lays particular emphasis upon the fact that it is quite incorrect to consider
fatalities in the epidemic as due to influenza uncomplicated by bronchopneumonia.
Blanton and Irons[34] speak of influenza as an “antecedent respiratory infection” of
undetermined etiology, and believe that pneumonia when it occurs is due to
autogenous infection by a variety of secondary invaders, principally of the
pneumococcus and streptococcus groups. Hall, Stone, and Simpson[35] regard
pneumonia strictly as a complication and quite distinct from influenza itself. Synnott
and Clark[36] believe that the infection is characterized by a progressive intense
exudative inflammation of the respiratory tract often terminating in an aspiration
pneumonia with a variety of conditions found at autopsy and a multiplicity of
secondary organisms responsible for the fatal termination. B. influenzæ was usually
found but always with other organisms. Friedlander and his collaborators[37] speak
of a fulminating fatal type of influenza with acute inflammatory pulmonary edema,
but regard true bronchopneumonia as secondary, due to infection with
pneumococcus or S. hemolyticus. B. influenzæ was not found more frequently than
under normal conditions. Brem[38] and his collaborators present a clear cut clinical
picture both of influenza and the secondary pneumonia to which it predisposes,
regarding the latter as definitely due to secondary infection with pneumococcus,
streptococcus or B. influenzæ, the virus of influenza being unknown. Ely[39] and his
collaborators make no distinction between influenza and pneumonia, and
apparently consider the epidemic due to a hemolytic streptococcus of indefinite and
inconstant characters. The Camp Lewis Pneumonia Unit[40] states “the process
[influenza], whether mild or severe, is etiologically and pathologically the
same; * * *.” B. influenzæ was not found. In a report of The American Public
Health Association[41] it is stated that deaths resulting from influenza are commonly
due to pneumonias resulting from an invasion of the lungs by one or more forms of
streptococci, by one or more forms of pneumococci, or by the so-called influenza
bacillus. This invasion is apparently secondary to the initial attack. Wolbach[42]
found B. influenzæ in a high proportion of cases, not infrequently in pure culture in
the lung, and believes that there is a true influenzal pneumonia whether B.
influenzæ is the cause of the primary disease or not. Spooner, Scott and Heath[43]
isolated B. influenzæ in a high percentage of cases and consider it reasonable to
suppose that it was the prime factor in the epidemic. Kinsella[44] found B. influenzæ
infrequently and regards it as a secondary invader. MacCallum[45] regards B.
influenzæ as a secondary invader and believes that it is responsible for a form of
purulent bronchitis and bronchopneumonia following certain cases of influenza.
Pritchett and Stillman[46] found B. influenzæ in 93 per cent of cases of influenza and
bronchopneumonia. Hirsch and McKinney[47] state that B. influenzæ played no rôle
in the epidemic at Camp Grant and apparently consider it due to a specially virulent
pneumococcus.
No further references to the extensive literature of the recent pandemic seem
necessary, since those cited above serve to illustrate the various points of view that
exist. A similar diversity of opinion may be found in the reports from foreign
sources.
It would appear that much of the divergence of opinion that has been formed
has depended to a considerable extent upon the conditions under which cases have
been observed. This is clearly brought out by contrasting the experience of
Fantus[39] dealing with private cases in civilian practice, where pneumonia was
relatively uncommon, with that of others dealing only with cases in large hospitals,
where those admitted have been in large part selected seriously ill patients with a
high incidence of pneumonia, the milder cases comprising from 60 to 90 per cent
of those attacked by influenza never reaching the hospital. Variations in opinion
with respect to the bacteriology of the epidemic, especially in regard to B.
influenzæ, would appear to be due for the most part to differences in bacteriologic
technic, in some degree to differences in interpretation. Accumulating evidence can
leave little doubt that B. influenzæ was at least extraordinarily and universally
prevalent throughout the period of the epidemic and thereafter, and that earlier
reports of failure to find it were due to the use of methods unsuitable for its
detection and isolation.
The opportunity afforded the commission at Camp Pike to devote their full time
to a systematic and correlated group study of the epidemic simultaneously from
many aspects throughout its whole course made it apparent that influenza per se is
in the large majority of instances, in spite of the initial picture of profound
prostration, a relatively mild disease which tends to rapid spontaneous recovery.
This opinion is supported by the fact that the disease during the first waves of the
epidemic in this country, which it is now recognized occurred pretty generally in the
army camps during the spring of 1918, was so mild that it attracted only passing
attention, since the disease at that time was not sufficiently virulent to predispose
to any alarming amount of pneumonia. With the return of the epidemic in the late
summer and early fall, however, the disease had attained such a high degree of
virulence that it predisposed to an appalling amount of severe and often rapidly
fatal pneumonia, which often detracted attention from the real nature of the
preceding disease. Yet even during the fall epidemic from 60 to 90 per cent of the
cases of influenza proceeded to rapid recovery without developing complications.
On this ground alone it would seem only logical to regard pneumonia strictly as a
complication of influenza rather than as an essential part of the disease,
irrespective of whether the pneumonia may be caused by the primary cause of
influenza or not. The complexity of the clinical features, the bacteriology and
pathology of the pneumonias following influenza lend further support to this
opinion.
It seems better, therefore, to consider influenza first as a disease by itself and
subsequently to take up the question of pneumonia and the relation of influenza to
it.
The most striking clinical features of influenza are its epidemic character, its
involvement of the respiratory tract, its extremely prostrating effect, and the often
surprising rapidity with which the individual cures himself. These features strongly
suggest that the etiologic agent of the disease is an organism subject to rapid
changes in virulence; that it is confined to the respiratory tract where it produces a
superficial inflammatory reaction giving rise to the characteristic symptoms of
coryza, pharyngitis and tracheitis; that it elaborates a poison, possibly a true toxin,
readily absorbed by the lymphatics, the effect of which is manifested in the
profound prostration, severe aching pains, erythema, and leucopenia; and that it
may either disappear promptly from the respiratory mucous membrane at time of
recovery or may persist, leading a relatively saprophytic existence for an indefinite
period of time, being no longer harmful to the individual, at least more than locally,
because of an acquired immunity. Furthermore, in our opinion, the very brief
incubation period suggests that the disease is bacterial in origin, rather than that it
is analogous to the exanthemata, the majority of which present a comparatively
long, fairly constant, incubation period.
B. influenzæ has characteristics in accord with the clinical features of influenza. It
is an organism of very labile virulence; it is always present in our experience on the
mucous membranes of the respiratory tract in early uncomplicated cases of
influenza, often in overwhelming numbers; in only very exceptional instances, in
adults at least, does it invade the body producing a general infection, as the
numerous reports of negative blood cultures testify; recent investigations by
Parker[48] and others indicate that it is capable of producing a toxin quickly fatal for
rabbits; it is predominantly present in the respiratory tract during the active stage
of the disease and disappears in a considerable proportion of cases at time of
recovery, while in others, more particularly those that develop an extensive
secondary bronchitis and bronchiectasis it may persist for an indefinite period of
time.
It is, of course, fully appreciated that the foregoing is in the main merely
argumentative reasoning and it is put forth only to suggest that B. influenzæ merits
a much closer scrutiny with respect to its etiologic relationship to influenza than the
trend of present opinion has awarded it.
Although there remains some difference of opinion as to the relation of influenza
to pneumonia, the majority of observers concur in regarding pneumonia as a
complication and this would seem to be the only logical interpretation of the facts
available. The same may be said with respect to purulent bronchitis and
bronchiectasis. It is of considerable significance in this connection that pneumonia
following influenza presents no uniform clinical picture, no uniform bacteriology and
no uniform pathology. Whether the predisposition of patients with influenza to
contract pneumonia is preponderantly due to lowering of general resistance to
infection by the extremely prostrating effect of the disease and the inhibition of
leucocytic defense, or to a destruction of local resistance against bacterial invasion
by reason of profound injury to the bronchial mucosa, or to a combination of both
factors, is difficult to say. It seems most probable that both are concerned. At any
rate it seems clear that in the presence of influenza a considerable variety of
organisms which under ordinary conditions do not find lodgement in the lungs are
able to gain access to the lower respiratory tract and produce pneumonia.
CHAPTER III
SECONDARY INFECTION IN THE WARD TREATMENT
OF INFLUENZA AND PNEUMONIA

Eugene L. Opie, M.D.; Francis G. Blake, M.D.; James C. Small, M.D.; and Thomas
M. Rivers, M.D.

One of the most pressing problems that presented itself in the care of
influenza and pneumonia patients in the army cantonments during the recent
epidemic was the danger of secondary contact infection because of the
overcrowding of the base hospitals, nearly all of which were taxed far beyond
the limits of their capacity. That this danger was very real was fully
demonstrated by certain studies in ward infection that this commission was
able to make at Camp Pike[49]. It is the purpose of the present section of the
report to present these studies and to discuss the means whereby this
danger may be most successfully met.
It is perhaps well, first to define exactly what is meant by secondary
contact infection in influenza and pneumonia. In our experience at Camp Pike
it was found that a very large percentage of the pneumonias following
influenza were accompanied by secondary infection with pneumococcus,
some few being caused by hemolytic streptococcus. The types of
pneumococcus encountered were almost entirely those that are found
normally in the mouths of healthy men, approximately 85 per cent being
Types II atypical, III, and IV. It has been generally accepted that infection
with these types of pneumococci is usually autogenous—that is, that under
the proper conditions of lowered resistance an individual becomes infected
with the pneumococcus that he carries in his own mouth. Many observations
made during the course of the present work have suggested that this is
probably not so in many instances and that the influenza patient may not be
so much in danger from the pneumococcus that he normally carries in his
own mouth as he is from that carried by his neighbor, in other words, he is in
danger from contact infection. The same considerations hold true with
respect to hemolytic streptococcus infection. Secondary contact infection in
cases of already existing pneumonia following influenza were found to occur
frequently. These were for the most part caused by hemolytic streptococcus
infection superimposed upon a pneumococcus pneumonia. Many instances of
double pneumococcus infection, however, either coincident with or following
one another were encountered.
Secondary Infection with S. Hemolyticus in
Pneumonia
Pneumonia caused by streptococci was repeatedly observed[50] during the
pandemic of influenza which occurred in 1889–90. With clearer recognition of
the characters which distinguish varieties of streptococci several observers
have shown that secondary infection with hemolytic streptococci may occur
during the course of pneumonia and though definite evidence has been
lacking have suggested that it may be acquired within hospital wards. That a
similar secondary infection with S. hemolyticus in pneumococcus pneumonias
following influenza occurred not infrequently at Camp Pike during the
epidemic was shown by bacteriologic studies made during life and at autopsy
in a considerable series of cases. During the early days of the epidemic of
influenza, secondary streptococcus infection was almost entirely limited to
certain wards which were opened for the care of the rapidly increasing
number of patients with pneumonia. During this period these wards were
overcrowded, organization was incomplete, and the opportunities for transfer
of infection from patient to patient were almost unlimited. The spread of
streptococcus contagion and its fatal effect may be clearly brought out by
comparison of these wards with wards that had long been organized for the
care of patients with pneumonia.
Ward 3 had been in use for the care of patients with pneumonia for some
time prior to the outbreak of influenza. It was provided with sheet cubicles
and conducted by medical officers, nurses and enlisted men accustomed to
the care of patients with pneumonia, ordinary precautions being taken
against transfer of infection from one patient to another. The data in Table
XVII show the average number of patients in the ward, the number of new
cases of pneumonia admitted, and the number of deaths among patients
admitted during the corresponding period, for three periods of ten days each
from September 6 to October 5. The types of infection in fatal cases as
determined by cultures taken at autopsy are also shown.
Table XVII

Pneumonia in Ward 3

AVERAGE NUMBER TOTAL DEATHS CULTURES AT AUTOPSY


NUMBER OF AMONG PATIENTS
OF PATIENTS ADMITTED
PATIENTS ADMITTED DURING THE
IN WARD CORRESPONDING
PERIOD
NUMBER PER PNEUMOCOCCUS S. UNDETERMINED
CENT HEMOLYTICUS (NO AUTOPSY)
Sept. 18.6 11 3 27.2 3 0 0
6–15
Sept. 46.1 52 16 30.7 13 1 2
16–25
Sept. 58.6 23 8 34.7 5 1 2
26–
Oct. 5

During the period from September 6 to 15, just prior to the outbreak of
influenza in epidemic proportions, the ward had an average population of
18.6 patients. The total number of new patients admitted was 11, of whom 3
died, a mortality of 27.2 per cent. All these cases were pneumococcus
pneumonias as determined by bacteriologic examination of the sputum at
time of admission. The 3 fatal cases showed pneumococcus infection at
autopsy. During the second period, from September 16 to 25, with the
outbreak of the epidemic of influenza, the ward rapidly filled with new cases
of pneumonia, attaining an average population of 46.1 patients. Of the 52
new cases admitted 16 died, a mortality of 30.7 per cent. Again all the cases
admitted during this period in which bacteriologic examination of the sputum
was made, were found to be pneumococcus pneumonias with one exception.
This case, admitted on September 21 and dying two days later, had a
hemolytic streptococcus pneumonia. Fortunately, though quite by accident,
he was placed in a bed at one end of the porch and no transmission of
streptococcus infection to other cases in the ward took place. At autopsy 13
cases showed pneumococcus infection; the foregoing case, hemolytic
streptococcus. During the third period from September 26 to October 5 the
ward became even more crowded, having an average of 58.6 patients; 23
new cases were admitted, 8 of whom died, a mortality of 34.7 per cent.
Autopsy showed that 5 of these were pneumococcus pneumonias and 1 was
caused by hemolytic streptococcus infection. It is noteworthy that the death
rate from pneumonia gradually increased as the ward became more and
more crowded. This may possibly be attributed in part to the increasing
severity of the pneumonia during the early days of the influenza epidemic.
That it was in part directly due to secondary contact infection with
pneumococcus will be shown when the transmission of pneumococcus
infection is discussed. In spite of the overcrowding of the ward the
introduction of 2 cases of streptococcus pneumonia did not cause an
outbreak of streptococcus infection. Whether this was due to precautions
taken against the transfer of infection or was merely a matter of good luck is
difficult to say, in view of the fact that a considerable amount of transfer of
pneumococcus infection from one patient to another did occur.
Ward 8 had long been used for the care of colored patients with
pneumonia. As in Ward 3 cubicles were in use and ordinary precautions
against the transfer of infection were used. The data are presented in Table
XVIII.
Table XVIII

Pneumonia in Ward 8

AVERAGE NUMBER TOTAL DEATHS CULTURES AT AUTOPSY


NUMBER OF AMONG
OF PATIENTS PATIENTS
PATIENTS ADMITTED ADMITTED
IN WARD DURING THE
CORRESPONDING
PERIOD
NUMBER PER PNEUMOCOCCUS S. UNDETERMINED
CENT HEMOLYTICUS (NO AUTOPSY)
Sept.
6–20 25.5 18 2 11.1 2 0 0
Sept. 46.1 59 20 33.9 10 1 9
21–
Oct. 5

During the period from September 6 to 20, prior to the outbreak of


influenza in epidemic proportions among the colored troops, the ward had an
average population of 25.5 patients; 18 new cases of pneumonia were
admitted during this period, all of whom were pneumococcus pneumonias as
determined by bacteriologic examination of the sputum at time of admission
to the ward. Only 2 died, a mortality of 11.1 per cent, autopsy cultures
showing pneumococcus in both cases. All these patients were treated on the
porch of the ward while they were acutely sick. During the second period
from September 21 to October 5, when the influenza epidemic was at its
height, the ward rapidly filled with active cases of pneumonia and became
distinctly crowded. It contained an average of 46.1 patients, but had actually
reached a population of 64 patients at the end of the period. Of the 59 new
cases admitted, 20 died, a mortality of 33.9 per cent, 10 with pneumococcus
pneumonia, one with hemolytic streptococcus pneumonia. In 9 there was no
autopsy. The conditions in Ward 8 were quite analogous to those in Ward 3.
In spite of the overcrowding during the second period no outbreak of
secondary infection with S. hemolyticus occurred, but secondary
pneumococcus infection did occur as will be shown below.
In contrast with these two wards are Wards 1 and 2 in which widespread
secondary contact infection with S. hemolyticus took place. Ward 2 was
opened September 26, at the beginning of the period when 20 new wards for
pneumonia were organized. From September 26 to October 1 the cubicle
system was not in use, the ward was crowded, organization was imperfect,
and few precautions were taken to prevent transfer of infection from one
patient to another. On October 2 the cubicle system was installed and
precautions against transfer of infection were instituted. The data are shown
in Table XIX.
Table XIX

Pneumonia in Ward 2

TOTAL DEATHS
AMONG PATIENTS
AVERAGE ADMITTED
NUMBER CULTURES AT AUTOPSY
NUMBER DURING THE
OF
OF CORRESPONDING
PATIENTS
PATIENTS PERIOD
ADMITTED
IN WARD
PER S. UNDETERMINED
NUMBER PNEUMOCOCCUS
CENT HEMOLYTICUS (NO AUTOPSY)
Sept.
10 10
26
Sept.
27 17 40 27 67.5 0 23 4
27
Sept.
40 13
28
Sept.
51 12
29
Sept. 17 6 35.3 2 2 2
49 1
30
Oct. 1 43 4
Oct. 2 47 6
Oct. 3 42 0 10 4 40.0 2 1 1
Oct. 4 41 4

During the first three days 40 patients with pneumonia were admitted to
the ward. Of these 40 patients, 27 died, a mortality of 67.5 per cent. Cultures
at autopsy showed that 23 of these died with hemolytic streptococcus
infection, none of pneumococcus infection. In four there was no autopsy. To
appreciate the full significance of these figures it must be emphasized that
these patients at time of admission to the ward in no way differed from those
admitted to Ward 3 during the corresponding period and were not in any
sense selected cases. The type of infection in 9 of these patients had been
determined by bacteriologic examination of the sputum just prior to or
immediately after admission to the ward before opportunity for secondary
contact infection in this ward had occurred. All 9 were shown to have
pneumococcus pneumonia free from hemolytic streptococci at that time. All 9
died, 7 with secondary streptococcus infection as shown by cultures taken at
autopsy, 1 with a secondarily acquired Pneumococcus Type III infection—
sputum showed a Pneumococcus Type IV on admission—and in 1 there was
no autopsy. In view of the fact that bacteriologic examination of the sputum
in cases of pneumonia following influenza had shown that the large majority
of them were due to pneumococcus infection, it is probable that most of the
other cases of pneumonia admitted to this ward were pneumococcus
pneumonias at time of admission, and that they acquired the streptococcus
infection after admission.
During the next three days 17 new patients were admitted, of whom 6
died, a mortality of 35.3 per cent. Cultures at autopsy showed pneumococcus
infection in 2, streptococcus in 2. It is noteworthy that the porch was first put
into use on September 29. Of the 12 patients admitted on this date, 8 were
treated throughout the acute stage of their illness on the porch. Of these 8
patients but one died, of a Pneumococcus Type IV infection and none
became infected with S. hemolyticus. From October 4 to October 6, 10
patients were admitted, of whom 4 died. Cultures at autopsy showed
pneumococcus infection in 2, hemolytic streptococcus in 1.
The widespread prevalence of hemolytic streptococcus infection in this
ward as compared with its almost entire absence in Wards 3 and 8 is very
striking. Cultures made during life and at autopsy have shewn clearly that it
was due to rapid spread of contagion throughout the ward. The almost
unlimited opportunities for transfer of infection from patient to patient,
during the first six days the ward was in use, undoubtedly greatly facilitated
this spread. From the data available it is impossible to state exactly when and
by which patients hemolytic streptococcus infection was introduced into the
ward, but it must have been very early since the death rate was very high
from the beginning, and the first 23 cases coming to autopsy died with
streptococcus infection.
Ward 1 was opened on September 24. From that date until October 2 no
cubicles were in use and few precautions were taken against transfer of
infection. On October 2 cubicles were installed and ordinary precautions to
prevent transfer of infection were instituted. On October 6 the ward was
closed to further admissions. The data presented in Table XX are divided into
two periods, because on September 29 and 30, 4 patients with streptococcus
pneumonia were admitted to the ward.
Table XX

Pneumonia in Ward 1

AVERAGE NUMBER TOTAL DEATHS CULTURES AT AUTOPSY


NUMBER OF AMONG
OF PATIENTS PATIENTS
PATIENTS ADMITTED ADMITTED
IN WARD DURING THE
CORRESPONDING
PERIOD
NUMBER PER PNEUMOCOCCUS S. UNDETERMINED
CENT HEMOLYTICUS (NO AUTOPSY)
Sept. 35.8 34 11 32.3 5 3 3
24–29
Sept. 55.3 40 24 60.0 6 14 4
30–
Oct. 5

During the first period from September 24 to 29 the ward contained an


average of 35.8 patients, being only moderately crowded; 34 cases of
pneumonia were admitted, of whom 11 died, a mortality of 32.3 per cent. It
is noteworthy that deaths among this group which occurred prior to
September 30 were due to pneumococcus infection with one exception, a
patient entering the ward on September 26 and dying the following day. Of
the other 2 patients in this group who died with hemolytic streptococcus
pneumonia, 1 was admitted to the ward on September 25, was shown to be
free from S. hemolyticus on September 30, and died on October 12 with a
secondarily acquired streptococcus pneumonia and empyema; the other was
admitted on September 29 with streptococcus pneumonia and died the
following day.
During the second period from September 30 to October 5 the ward
contained an average of 55.3 patients, being very overcrowded; 40 new
cases of pneumonia were admitted of whom 24 died, a mortality of 60 per
cent. Cultures taken at autopsy showed that 6 died of pneumococcus
pneumonia, 14 with hemolytic streptococcus infection. As in Ward 2, patients
admitted to this ward were in no way selected and were probably, as
experience has shown, in large part pneumococcus pneumonias at time of
admission. The widespread dissemination of hemolytic streptococcus and its
fatal effect following the introduction of the organism on September 29 and
30 is only too evident.
Table XXI

Secondary Infection with Pneumococcus Type II

NAME BED ADMITTED PNEUMOCOCCUSIN SECONDARY


OCCUPIED SPUTUM ON INFECTION
ADMISSION DATE PNEUMOCOCCUS
AT AUTOPSY
Pvt. No. 6 Sept. 17 IV Sept. II [51]

Wolfe 23
Pvt. No. 5 Sept. 9 IV Sept. II
Pullam 24
Pvt. No. 3 Sept. 16 II
Swain
Secondary Infection with Pneumococcus in
Pneumonia
The foregoing studies have shown that hemolytic streptococcus infection
may spread by contagion throughout an entire ward with great rapidity.
Other observations have demonstrated that pneumococcus infection may be
transmitted in the same way. Only three instances of this nature will be cited.
The first occurred in Ward 3 (Table XXI). Between September 6 and 16 no
cases of pneumonia caused by Pneumococcus Type II had been admitted to
the ward. On September 16 Pvt. Swain was admitted to the ward and placed
in Bed 3. Bacteriologic examination of his sputum showed that his
pneumonia was caused by Pneumococcus Type II. At this time Pvt. Pullam,
who had been admitted to the ward on September 9 with a pneumococcus
Type IV pneumonia, occupied Bed 5 separated from Bed 3 by one intervening
bed. He had had his crisis on September 14 and was doing well, his
temperature being normal. On September 24 he developed a second attack
of pneumonia and died on September 30. Cultures at autopsy showed
Pneumococcus Type II in heart’s blood and lung, Pneumococcus Type II and
B. influenzæ in the right bronchus. Pvt. Wolfe was admitted to the ward with
bronchopneumonia on September 17 and placed in Bed 6 next to Pvt.
Pullam. Pneumococcus Type IV and B. influenzæ were found in his sputum.
His temperature had fallen to normal by lysis on September 21 and he was
doing well. On September 23 his temperature suddenly rose and he
developed a second attack of pneumonia. Pneumococcus Type II was
isolated by blood culture on this date. He recovered. In both instances
Pneumococcus Type II was acquired after the admission of a patient with a
Pneumococcus Type II pneumonia, the opportunity for contact infection
having been favored by the association of these patients in adjoining beds.
Table XXII

Secondary Infection with Pneumococcus Type II

SECONDARY
PNEUMOCOCCUS INFECTION
BED
NAME ADMITTED IN SPUTUM ON
OCCUPIED PNEUMOCOCCUS
ADMISSION DATE
AT AUTOPSY
Pvt. Smith No. 26 Sept. 18 II II
Pvt. Sept.
No. 28 Sept. 17 Atyp. II II
Thompson 21
Pvt. Sept.
No. 30 Sept. 16 IV II
Linehan 26
The second instance is almost identical and occurred on the opposite side
of Ward 3 at about the same time (Table XXII). Pvt. Linehan was admitted on
September 16 and placed in Bed 30. Pneumococcus Type IV was found in his
sputum. Pvt. Thompson was admitted the following day with a
Pneumococcus II atypical pneumonia and placed in Bed 28. The next day
Pvt. Smith was admitted and placed in Bed 26. Pneumococcus Type II was
found in his sputum. On September 19 Pvt. Thompson recovered by crisis
and was doing well. On September 21 he had a chill, his temperature rose to
104.4° F. and he developed a second attack of pneumonia. He died on
September 29; cultures at autopsy showing Pneumococcus Type II in heart’s
blood and left pleural cavity, Pneumococcus Type II and B. influenzæ in
bronchus and lung. Pvt. Linehan had begun to improve on September 24 and
his temperature was falling by lysis. On September 26 he became worse,
developed signs of pericarditis and died on September 30. Cultures from
lungs and bronchus at autopsy showed Pneumococcus Type II and B.
influenzæ. In both instances the fatal secondary infection with
Pneumococcus Type II was undoubtedly acquired from Pvt. Smith in the
nearby bed.
The third instance occurred in Ward 8 (Table XXIII). Pvts. Lewis and Scott
were admitted on September 21 and were placed in adjoining beds, 50 and
51. Lewis showed Pneumococcus Type I in his sputum, Scott Pneumococcus
II atypical. The following day Pvts. Pighee, Jones, and Columbus were
admitted and given Beds 48, 49 and 53 respectively. All showed
Pneumococcus II atypical in the sputum. Pvt. Lewis with Pneumococcus Type
I pneumonia recovered by crisis on September 29. His temperature remained
normal until October 2 when it suddenly rose to 104.2° F. He developed a
second attack of pneumonia and died on October 8. Cultures at autopsy from
heart’s blood and lung showed Pneumococcus II atypical, from the bronchus
Welcome to Our Bookstore - The Ultimate Destination for Book Lovers
Are you passionate about books and eager to explore new worlds of
knowledge? At our website, we offer a vast collection of books that
cater to every interest and age group. From classic literature to
specialized publications, self-help books, and children’s stories, we
have it all! Each book is a gateway to new adventures, helping you
expand your knowledge and nourish your soul
Experience Convenient and Enjoyable Book Shopping Our website is more
than just an online bookstore—it’s a bridge connecting readers to the
timeless values of culture and wisdom. With a sleek and user-friendly
interface and a smart search system, you can find your favorite books
quickly and easily. Enjoy special promotions, fast home delivery, and
a seamless shopping experience that saves you time and enhances your
love for reading.
Let us accompany you on the journey of exploring knowledge and
personal growth!

ebookgate.com

You might also like