0% found this document useful (0 votes)
8 views

Algorithms On Trees And Graphs With Python Code 2nd Edition Gabriel Valiente download

The document presents the second edition of 'Algorithms on Trees and Graphs with Python Code' by Gabriel Valiente, which has been extensively used for graduate teaching and research. This edition includes detailed pseudocode, Python implementations of algorithms, and new material on graph traversal techniques and bipartite matching. It serves as a comprehensive resource for understanding and implementing algorithms related to trees and graphs, suitable for upper undergraduate and graduate courses.

Uploaded by

peywljfcwg3493
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

Algorithms On Trees And Graphs With Python Code 2nd Edition Gabriel Valiente download

The document presents the second edition of 'Algorithms on Trees and Graphs with Python Code' by Gabriel Valiente, which has been extensively used for graduate teaching and research. This edition includes detailed pseudocode, Python implementations of algorithms, and new material on graph traversal techniques and bipartite matching. It serves as a comprehensive resource for understanding and implementing algorithms related to trees and graphs, suitable for upper undergraduate and graduate courses.

Uploaded by

peywljfcwg3493
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 77

Algorithms On Trees And Graphs With Python Code

2nd Edition Gabriel Valiente download

https://ebookbell.com/product/algorithms-on-trees-and-graphs-
with-python-code-2nd-edition-gabriel-valiente-35074452

Explore and download more ebooks at ebookbell.com


Here are some recommended products that we believe you will be
interested in. You can click the link to download.

Algorithms On Trees And Graphs 1st Edition Prof Dr Gabriel Valiente


Auth

https://ebookbell.com/product/algorithms-on-trees-and-graphs-1st-
edition-prof-dr-gabriel-valiente-auth-4199916

Algorithms On Trees And Graphs Valiente G

https://ebookbell.com/product/algorithms-on-trees-and-graphs-
valiente-g-4580170

Algorithms On Strings 1st Maxime Crochemore Christophe Hancart

https://ebookbell.com/product/algorithms-on-strings-1st-maxime-
crochemore-christophe-hancart-1494028

Optimization Algorithms On Matrix Manifolds Course Book Pa Absil R


Mahony Rodolphe Sepulchre

https://ebookbell.com/product/optimization-algorithms-on-matrix-
manifolds-course-book-pa-absil-r-mahony-rodolphe-sepulchre-51950524
Cryptographic Algorithms On Reconfigurable Hardware 1st Edition
Francisco Rodrguezhenrquez

https://ebookbell.com/product/cryptographic-algorithms-on-
reconfigurable-hardware-1st-edition-francisco-rodrguezhenrquez-4191924

Optimization Algorithms On Matrix Manifolds Illustrated Edition Pa


Absil

https://ebookbell.com/product/optimization-algorithms-on-matrix-
manifolds-illustrated-edition-pa-absil-1075844

Average Case Analysis Of Algorithms On Sequences 1st Edition Wojciech


Szpankowski

https://ebookbell.com/product/average-case-analysis-of-algorithms-on-
sequences-1st-edition-wojciech-szpankowski-4645760

Quantum Computing And Artificial Intelligence Training Machine And


Deep Learning Algorithms On Quantum Computers Pethuru Raj Editor
Abhishek Kumar Editor Ashutosh Kumar Dubey Editor Surbhi Bhatia Editor
Oswalt Manoj S Editor
https://ebookbell.com/product/quantum-computing-and-artificial-
intelligence-training-machine-and-deep-learning-algorithms-on-quantum-
computers-pethuru-raj-editor-abhishek-kumar-editor-ashutosh-kumar-
dubey-editor-surbhi-bhatia-editor-oswalt-manoj-s-editor-51438668

Learning Predictive Analytics With Python Gain Practical Insights Into


Predictive Modelling By Implementing Predictive Analytics Algorithms
On Public Datasets With Python Gulipalli

https://ebookbell.com/product/learning-predictive-analytics-with-
python-gain-practical-insights-into-predictive-modelling-by-
implementing-predictive-analytics-algorithms-on-public-datasets-with-
python-gulipalli-20640178
Texts in Computer Science

Gabriel Valiente

Algorithms
on Trees
and Graphs
With Python Code
Second Edition
Texts in Computer Science

Series Editors
David Gries, Department of Computer Science, Cornell University, Ithaca, NY,
USA
Orit Hazzan , Faculty of Education in Technology and Science, Technion—Israel
Institute of Technology, Haifa, Israel
More information about this series at http://www.springer.com/series/3191
Gabriel Valiente

Algorithms on Trees
and Graphs
With Python Code
Second Edition

123
Gabriel Valiente
Department of Computer Science
Technical University of Catalonia
Barcelona, Spain

ISSN 1868-0941 ISSN 1868-095X (electronic)


Texts in Computer Science
ISBN 978-3-030-81884-5 ISBN 978-3-030-81885-2 (eBook)
https://doi.org/10.1007/978-3-030-81885-2

1st edition: © Springer-Verlag Berlin Heidelberg 2002


2nd edition: © The Editor(s) (if applicable) and The Author(s), under exclusive license to Springer Nature
Switzerland AG 2021
This work is subject to copyright. All rights are solely and exclusively licensed by the Publisher, whether
the whole or part of the material is concerned, specifically the rights of translation, reprinting, reuse of
illustrations, recitation, broadcasting, reproduction on microfilms or in any other physical way, and
transmission or information storage and retrieval, electronic adaptation, computer software, or by similar
or dissimilar methodology now known or hereafter developed.
The use of general descriptive names, registered names, trademarks, service marks, etc. in this
publication does not imply, even in the absence of a specific statement, that such names are exempt from
the relevant protective laws and regulations and therefore free for general use.
The publisher, the authors and the editors are safe to assume that the advice and information in this
book are believed to be true and accurate at the date of publication. Neither the publisher nor the
authors or the editors give a warranty, expressed or implied, with respect to the material contained
herein or for any errors or omissions that may have been made. The publisher remains neutral with regard
to jurisdictional claims in published maps and institutional affiliations.

This Springer imprint is published by the registered company Springer Nature Switzerland AG
The registered company address is: Gewerbestrasse 11, 6330 Cham, Switzerland
To my child Aleksandr,
six years old,
who is eager to grow
and read it all
Preface to the Second Edition

The first edition of this book has been extensively used for graduate teaching and
research all over the world in the last two decades. We have listed hundreds of
citing publications in Appendix C, including books, scientific articles in journals
and conference proceedings, M.Sc. and Ph.D. theses, and even United States
patents.
In this new edition, we have substituted detailed pseudocode for both the literate
programming description and the implementation of the algorithms using the
LEDA library of efficient data structures and algorithms. Although the pseudocode
is detailed enough to allow for a straightforward implementation of the algorithms
in any modern programming language, we have added a proof-of-concept imple-
mentation in Python of all the algorithms in Appendix A. This is, therefore, a
thoroughly revised and extended edition.
Regarding new material, we have added an adjacency map representation of
trees and graphs, and both maximum cardinality and maximum weight bipartite
matching as an additional application of graph traversal techniques. Further, we
have revised the end-of-chapter problems and exercises and have included solutions
to all the problems in Appendix B.
It has been a pleasure for the author to work out editorial matters together with
Sriram Srinivas and, especially, Wayne Wheeler of Springer Nature, whose
standing support and encouragement have made this new edition possible.
Last, but not least, any minor errors found so far have been corrected in this
second edition, the bibliographic notes and references have been updated, and the
index has been substantially enhanced. Even though the author and the publisher
have taken much care in the preparation of this book, they make no representation,
express or implied, with regard to the accuracy of the information contained herein
and cannot accept any legal responsibility or liability for incidental or consequential
damages arising out of the use of the information, algorithms, or program code
contained in this book.

Barcelona, Spain Gabriel Valiente


June 2021

vii
Preface to the First Edition

Graph algorithms, a long-established subject in mathematics and computer science


curricula, are also of much interest to disciplines such as computational molecular
biology and computational chemistry. This book goes beyond the classical graph
problems of shortest paths, spanning trees, flows in networks, and matchings in
bipartite graphs, and addresses further algorithmic problems of practical application
on trees and graphs. Much of the material presented on the book is only available in
the specialized research literature.
The book is structured around the fundamental problem of isomorphism. Tree
isomorphism is covered in much detail, together with the related problems of
subtree isomorphism, maximum common subtree isomorphism, and tree compari-
son. Graph isomorphism is also covered in much detail, together with the related
problems of subgraph isomorphism, maximal common subgraph isomorphism, and
graph edit distance. A building block for solving some of these isomorphism
problems are algorithms for finding maximal and maximum cliques.
Most intractable graph problems of practical application are not even approx-
imable to within a constant bound, and several of the isomorphism problems
addressed in this book are no exception. The book can thus be seen as a companion
to recent texts on approximation algorithms [1, 16], but also as a complement to
previous texts on combinatorial and graph algorithms [2–15, 17].
The book is conceived on the ground of first, introducing simple algorithms for
these problems in order to develop some intuition before moving on to more
complicated algorithms from the research literature and second, stimulating grad-
uate research on tree and graph algorithms by providing together with the under-
lying theory, a solid basis for experimentation and further development.
Algorithms are presented on an intuitive basis, followed by a detailed exposition
in a literate programming style. Correctness proofs are also given, together with a
worst-case analysis of the algorithms. Further, full C++ implementation of all the
algorithms using the LEDA library of efficient data structures and algorithms is
given along the book. These implementations include result checking of imple-
mentation correctness using correctness certificates.
The choice of LEDA, which is becoming a de-facto standard for graduate
courses on graph algorithms throughout the world is not casual, because it allows
the student, lecturer, researcher, and practitioner to complement algorithmic graph

ix
x Preface to the First Edition

theory with actual implementation and experimentation, building upon a thorough


library of efficient implementations of modern data structures and fundamental
algorithms.
An interactive demonstration including animations of all the algorithms using
LEDA is given in an appendix. The interactive demonstration also includes visual
checkers of implementation correctness.
The book is divided into four parts. Part I has an introductory nature and consists
of two chapters. Chapter 1 includes a review of basic graph-theoretical notions and
results used along the book, a brief primer of literate programming, and an expo-
sition of the implementation correctness approach by result checking using cor-
rectness certificates. Chapter 2 is devoted exclusively to the fundamental
algorithmic techniques used in the book: backtracking, branch-and-bound,
divide-and-conquer, and dynamic programming. These techniques are illustrated by
means of a running example: algorithms for the tree edit distance problem.
Part II also consists of two chapters. Chapter 3 addresses the most common
methods for traversing general, rooted trees: depth-first prefix leftmost (preorder),
depth-first prefix rightmost, depth-first postfix leftmost (postorder), depth-first
postfix rightmost, breadth-first leftmost (top-down), breadth-first rightmost, and
bottom-up traversal. Tree drawing is also discussed as an application of tree
traversal methods. Chapter 4 addresses several isomorphism problems on ordered
and unordered trees: tree isomorphism, subtree isomorphism, and maximum
common subtree isomorphism. Computational molecular biology is also discussed
as an application of the different isomorphism problems on trees.
Part III consists of three chapters. Chapter 5 addresses the most common
methods for traversing graphs: depth-first and breadth-first traversal, which
respectively generalize depth-first prefix leftmost (preorder) and breadth-first left-
most (top-down) tree traversal. Leftmost depth-first traversal of an undirected
graph, a particular case of depth-first traversal, is also discussed. Isomorphism of
ordered graphs is also discussed as an application of graph traversal methods.
Chapter 6 addresses the related problems of finding cliques, independent sets, and
vertex covers in trees and graphs. Multiple alignment of protein sequences in
computational molecular biology is also discussed as an application of clique
algorithms. Chapter 7 addresses several isomorphism problems on graphs: graph
isomorphism, graph automorphism, subgraph isomorphism, and maximal common
subgraph isomorphism. Chemical structure search is also discussed as an applica-
tion of the different graph isomorphism problems.
Part IV consists of two appendices, followed by bibliographic references and an
index. Appendix A gives an overview of LEDA, including a simple C++ repre-
sentation of trees as LEDA graphs, and a C++ implementation of radix sort using
LEDA. The interactive demonstration of graph algorithms presented along the book
is put together in Appendix B. Finally, Appendix C contains a complete index to all
program modules described in the book.
This book is suitable for use in upper undergraduate and graduate level courses
on algorithmic graph theory. This book can also be used as a supplementary text in
basic undergraduate and graduate level courses on algorithms and data structures,
Preface to the First Edition xi

and in computational molecular biology and computational chemistry courses as


well. Some basic knowledge of discrete mathematics, data structures, algorithms,
and programming at the undergraduate level is assumed.
This book is based on lectures taught at the Technical University of Catalonia,
Barcelona between 1996 and 2002, and the University of Latvia, Riga between
2000 and 2002. Numerous colleagues at the Technical University of Catalonia have
influenced the approach to data structures and algorithms on trees and graphs
expressed in this book. In particular, the author would like to thank José L. Bal-
cázar, Rafel Casas, Jordi Cortadella, Josep Daz, Conrado Martnez, Xavier Mes-
seguer, Roberto Nieuwenhuis, Fernando Orejas, Jordi Petit, Salvador Roura, and
Maria Serna, to name just a few. It has been a pleasure to share teaching and
research experiences with them over the last several years.
The author would also like to thank Ricardo Baeza-Yates, Francesc Rosselló,
and Steven Skiena, for their standing support and encouragement, and Hans-Jörg
Kreowski, for supporting basic and applied research on graph algorithms within the
field of graph transformation. It has been a pleasure for the author to work out
editorial matters together with Alfred Hofmann, Ingeborg Mayer, and Peter Straßer
of Springer-Verlag. Special thanks are debt to the Technical University of Catalonia
for funding the sabbatical year during which this book was written, and to the
Institute of Mathematics and Computer Science, University of Latvia, in particular
to Jānis Bārzdiņš and Rūsiņš Freivalds, for hosting the sabbatical visit.

Barcelona, Spain Gabriel Valiente


July 2002

References

1. G. Ausiello, P. Crescenzi, G. Gambosi, V. Kahn, A. MarchettiSpaccamela, and M. Protasi.


Complexity and Approximation: Combinatorial Optimization Problems and their Approx-
imability Properties. Springer-Verlag, Berlin Heidelberg, 1999.
2. G. Chartrand and O. R. Oellermann. Applied and Algorithmic Graph Theory. McGraw-Hill,
New York, 1993.
3. N. Christofides. Graph Theory: An Algorithmic Approach. Academic Press, New York, 1975.
4. S. Even. GraphAlgorithms. Computer Science Press, Rockville MD,1979.
5. A. Gibbons. Algorithmic Graph Theory. Cambridge University Press, Cambridge, 1985.
6. M. C. Golumbic. Algorithmic Graph Theory and Perfect Graphs. Academic Press, New York,
1980.
7. D. L. Kreher and D. R. Stinson. Combinatorial Algorithms: Generation, Enumeration, and
Search. CRC Press, Boca Raton FL, 1999.
8. J. van Leeuwen. Graph algorithms. In Handbook of Theoretical Computer Science, volume A,
chapter 10, pages 525-631. Elsevier, Amsterdam, 1990.
9. J. A. McHugh. Algorithmic Graph Theory. Prentice Hall, Englewood Cliffs NJ, 1990.
10. K. Mehlhorn. Graph Algorithms and NP-Completeness, volume 2 of Data Structures and
Algorithms. Springer-Verlag, Berlin Heidelberg, 1984.
11. K. Mehlhorn and S. Naher. The LEDA Platform of Combinatorial and Geometric Computing.
Cambridge University Press, Cambridge, 1999.
xii Preface to the First Edition

12. C. H. Papadimitriou and K. Steiglitz. CombinatorialOptimization: Algorithms and Com-


plexity. Dover, Mineola, New York, 1998.
13. E. M. Reingold, 1. Nievergelt, and N. J. Deo. Combinatorial Algorithms: Theory and
Practice. Prentice Hall, Englewood Cliffs NJ, 1977.
14. S. Skiena. The Algorithm Design Manual. Springer-Verlag, Berlin Heidelberg, 1998.
15. R. E. Tarjan. Space-efficient Implementations of Graph Search Methods. ACM Transactions
on Mathematical Software. 1983 9(3), 326–339
16. V. V. Vazirani. Approximation Algorithms. Springer-Verlag, Berlin Heidelberg, 2001.
17. H. S. Wilf. Combinatorial Algorithms: An Update. SIAM, Philadelphia PA, 1989.
Contents

Part I Introduction
1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1 Trees and Graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Basic Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.3 Representation of Trees and Graphs . . . . . . . . . . . . . . . . . . . . . . 23
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Bibliographic Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
2 Algorithmic Techniques . . . ........ . . . . . . . . . . . . . . . . . . . . . . . 45
2.1 The Tree Edit Distance Problem . . . . . . . . . . . . . . . . . . . . . . . . 45
2.2 Backtracking . . . . . . . ........ . . . . . . . . . . . . . . . . . . . . . . . 55
2.3 Branch-and-Bound . . . ........ . . . . . . . . . . . . . . . . . . . . . . . 61
2.4 Divide-and-Conquer . . ........ . . . . . . . . . . . . . . . . . . . . . . . 64
2.5 Dynamic Programming ........ . . . . . . . . . . . . . . . . . . . . . . . 70
Summary . . . . . . . . . . . . . . . ........ . . . . . . . . . . . . . . . . . . . . . . . 77
Bibliographic Notes . . . . . . . ........ . . . . . . . . . . . . . . . . . . . . . . . 77
Problems . . . . . . . . . . . . . . . ........ . . . . . . . . . . . . . . . . . . . . . . . 78
Exercises . . . . . . . . . . . . . . . ........ . . . . . . . . . . . . . . . . . . . . . . . 79
References . . . . . . . . . . . . . . ........ . . . . . . . . . . . . . . . . . . . . . . . 80

Part II Algorithms on Trees


3 Tree Traversal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
3.1 Preorder Traversal of a Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
3.2 Postorder Traversal of a Tree . . . . . . . . . . . . . . . . . . . . . . . . . . 90
3.3 Top-Down Traversal of a Tree . . . . . . . . . . . . . . . . . . . . . . . . . 94
3.4 Bottom-Up Traversal of a Tree . . . . . . . . . . . . . . . . . . . . . . . . . 97
3.5 Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Bibliographic Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107

xiii
xiv Contents

Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
4 Tree Isomorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
4.1 Tree Isomorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
4.1.1 Ordered Tree Isomorphism . . . . . . . . . . . . . . . . . . . . . . 113
4.1.2 Unordered Tree Isomorphism . . . . . . . . . . . . . . . . . . . . 116
4.2 Subtree Isomorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
4.2.1 Top-Down Subtree Isomorphism . . . . . . . . . . . . . . . . . . 125
4.2.2 Top-Down Unordered Subtree Isomorphism . . . . . . . . . 127
4.2.3 Bottom-Up Subtree Isomorphism . . . . . . . . . . . . . . . . . 135
4.2.4 Bottom-Up Unordered Subtree Isomorphism . . . . . . . . . 138
4.3 Maximum Common Subtree Isomorphism . . . . . . . . . . . . . . . . . 144
4.3.1 Top-Down Maximum Common Subtree
Isomorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
4.3.2 Top-Down Unordered Maximum Common Subtree
Isomorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
4.3.3 Bottom-Up Maximum Common Subtree
Isomorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
4.3.4 Bottom-Up Unordered Maximum Common Subtree
Isomorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
4.4 Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
Bibliographic Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176

Part III Algorithms on Graphs


5 Graph Traversal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
5.1 Depth-First Traversal of a Graph . . . . . . . . . . . . . . . . . . . . . . . . 183
5.1.1 Leftmost Depth-First Traversal of a Graph . . . . . . . . . . . 190
5.2 Breadth-First Traversal of a Graph . . . . . . . . . . . . . . . . . . . . . . . 193
5.3 Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
Bibliographic Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Contents xv

6 Clique, Independent Set, and Vertex Cover . . . . . . . . . . . . . . . . . . . 219


6.1 Cliques, Maximal Cliques, and Maximum Cliques . . . . . . . . . . . 219
6.2 Maximal and Maximum Independent Sets . . . . . . . . . . . . . . . . . 234
6.3 Minimal and Minimum Vertex Covers . . . . . . . . . . . . . . . . . . . . 239
6.4 Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Bibliographic Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
7 Graph Isomorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
7.1 Graph Isomorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
7.1.1 An Algorithm for Graph Isomorphism . . . . . . . . . . . . . . 257
7.2 Graph Automorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
7.3 Subgraph Isomorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
7.3.1 An Algorithm for Subgraph Isomorphism . . . . . . . . . . . 266
7.4 Maximal Common Subgraph Isomorphism . . . . . . . . . . . . . . . . . 270
7.4.1 An Algorithm for Maximal Common Subgraph
Isomorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
7.5 Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
Bibliographic Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282

A: Implementation of the Algorithms in Python . . . . . . . . . . . . . . . . . . . . 287


B: Solutions to All Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
C: Citing Publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
Part I
Introduction
Introduction
1

1.1 Trees and Graphs

The notion of graph which is most useful in computer science is that of a directed
graph or just a graph. A graph is a combinatorial structure consisting of a finite
nonempty set of objects, called vertices, together with a finite (possibly empty) set
of ordered pairs of vertices, called directed edges or arcs.

Definition 1.1 A graph G = (V, E) consists of a finite nonempty set V of vertices


and a finite set E ⊆ V × V of edges. The order of a graph G = (V, E), denoted
by n, is the number of vertices, n = |V | and the size, denoted by m, is the number
of edges, m = |E|. An edge e = (v, w) is said to be incident with vertices v and w,
where v is the source and w the target of edge e, and vertices v and w are said to be
adjacent. Edges (u, v) and (v, w) are said to be adjacent, as are edges (u, v) and
(w, v), and also edges (v, u) and (v, w).

Graphs are often drawn as a set of points in the plane and a set of arrows, each
of which joins two (not necessarily different) points. In a drawing of a graph G =
(V, E), each vertex v ∈ V is drawn as a point or a small circle and each edge
(v, w) ∈ E is drawn as an arrow from the point or circle of vertex v to the point or
circle corresponding to vertex w.

Example 1.1 The graph G = (V, E) of Fig. 1.1 has order 7 and size 12. The
vertex set is V = {v1 , . . . , v7 } and the edge set is E = {e1 , . . . , e12 }, where e1 =
(v1 , v2 ), e2 = (v1 , v4 ), e3 = (v2 , v5 ), e4 = (v3 , v1 ), e5 = (v4 , v2 ), e6 = (v4 , v3 ),
e7 = (v4 , v6 ), e8 = (v4 , v7 ), e9 = (v5 , v4 ), e10 = (v5 , v7 ), e11 = (v6 , v3 ), and
e12 = (v7 , v6 ).

© The Author(s), under exclusive license to Springer Nature Switzerland AG 2021 3


G. Valiente, Algorithms on Trees and Graphs, Texts in Computer Science,
https://doi.org/10.1007/978-3-030-81885-2_1
4 1 Introduction

Fig. 1.1 A graph of order 7 1


1 2
and size 12
4 3
2 5
6 9
3 4 5

7 8
11 10

6 7
12

A vertex has two degrees in a graph, one given by the number of edges coming
into the vertex and the other given by the number of edges in the graph going out of
the vertex.

Definition 1.2 The indegree of a vertex v in a graph G = (V, E) is the number


of edges in G whose target is v, that is, indeg(v) = |{(u, v) | (u, v) ∈ E}|. The
outdegree of a vertex v in a graph G = (V, E) is the number of edges in G whose
source is v, that is, outdeg(v) = |{(v, w) | (v, w) ∈ E}|. The degree of a vertex v in
a graph G = (V, E) is the sum of the indegree and the outdegree of the vertex, that
is, deg(v) = indeg(v) + outdeg(v).

Example 1.2 The degree of the vertices in the graph of Fig. 1.1 is the following:

Vertex v1 v2 v3 v4 v5 v6 v7 sum
Indegree 1 2 2 2 1 2 2 12
Outdegree 2 1 1 4 2 1 1 12

As can be seen in Example 1.2, the sum of the indegrees and the sum of the
outdegrees of the vertices of the graph in Fig. 1.1 are both equal to 12, the number
of edges of the graph. As a matter of fact, there is a basic relationship between the
size of a graph and the degrees of its vertices, which will prove to be very useful in
analyzing the computational complexity of algorithms on graphs.

Theorem 1.1 Let G = (V, E) be a graph with n vertices and m edges, and let
V = {v1 , . . . , vn }. Then,

n 
n
indeg(vi ) = outdeg(vi ) = m .
i=1 i=1

Proof Let G = (V, E) be a graph. Every edge (vi , v j ) ∈ E contributes one to


indeg(v j ) and one to outdeg(vi ). 
1.1 Trees and Graphs 5

1 2 1 2 1 2

3 4 5 3 4 5 3 4 5

6 7 6 7 6 7

Fig. 1.2 A walk [v1 , v4 , v6 , v3 , v1 , v4 , v2 ], a trail [v1 , v4 , v2 , v5 , v4 , v6 , v3 ], and a path [v1 , v4 , v2 ,


v5 , v7 , v6 , v3 ] in the graph of Fig. 1.1

Walks, trails, and paths in a graph are alternating sequences of vertices and edges
in the graph such that each edge in the sequence is preceded by its source vertex and
followed by its target vertex. Trails are walks having no repeated edges, and paths
are trails having no repeated vertices.

Definition 1.3 A walk from vertex vi to vertex v j in a graph is an alternating


sequence
[vi , ei+1 , vi+1 , ei+2 , . . . , v j−1 , e j , v j ]
of vertices and edges in the graph, such that ek = (vk−1 , vk ) for k = i + 1, . . . , j. A
trail is a walk with no repeated edges, and a path is a trail with no repeated vertices
(except, possibly, the initial and final vertices). The length of a walk, trail, or path is
the number of edges in the sequence.

Since an edge in a graph is uniquely determined by its source and target vertices,
a walk, trail, or path can be abbreviated by just enumerating either the vertices
[vi , vi+1 , . . . , v j−1 , v j ] or the edges [ei+1 , ei+2 , . . . , e j ] in the alternating sequence
[vi , ei+1 , vi+1 , ei+2 , . . . , v j−1 , e j , v j ] of vertices and edges.

Example 1.3 The vertex sequence [v1 , v4 , v6 , v3 , v1 , v4 , v2 ] in Fig. 1.2 is a walk of


length 6 which is not a trail, [v1 , v4 , v2 , v5 , v4 , v6 , v3 ] is a trail of length 6 which is
not a path, and [v1 , v4 , v2 , v5 , v7 , v6 , v3 ] is a path of length 6.

Walks are closed if their initial and final vertices coincide.

Definition 1.4 A walk, trail, or path [vi , ei+1 , vi+1 , ei+2 , . . . , v j−1 , e j , v j ] is said
to be closed if vi = v j . A cycle is a closed path of length at least one.

Example 1.4 The vertex sequence [v1 , v4 , v6 , v3 , v1 ] in Fig. 1.3 is a cycle of


length 4.

The combinatorial structure of a graph encompasses two notions of the substruc-


ture. A subgraph of a graph is just a graph whose vertex and edge sets are contained
in the vertex and edge sets of the given graph, respectively. The subgraph of a graph
6 1 Introduction

1 2

3 4 5

6 7

Fig. 1.3 A cycle [v1 , v4 , v6 , v3 , v1 ] in the graph of Fig. 1.1

1 2 1 2

3 4 5 3 4 5

6 7 6 7

Fig. 1.4 A subgraph and an induced subgraph of the graph of Fig. 1.1

induced by a subset of its vertices has as edges the set of edges in the given graph
whose source and target belong to the subset of vertices.

Definition 1.5 Let G = (V, E) be a graph, and let W ⊆ V . A graph (W, S) is a


subgraph of G if S ⊆ E. The subgraph of G induced by W is the graph (W, E ∩
W × W ).

Example 1.5 The subgraph with vertex set {v1 , v2 , v4 , v6 , v7 } and edge set {(v1 , v2 ),
(v1 , v4 ), (v4 , v6 ), (v7 , v6 )} shown in Fig. 1.4 is not an induced subgraph. The
subgraph induced by {v1 , v2 , v4 , v6 , v7 } has edge set {(v1 , v2 ), (v1 , v4 ), (v4 , v2 ),
(v4 , v6 ), (v4 , v7 ), (v7 , v6 )}.

Undirected Graphs

The notion of graph which is most often found in mathematics is that of an undirected
graph. Unlike the directed edges or edges of a graph, edges of an undirected graph
have no direction association with them and therefore, no distinction is made between
the source and target vertices of an edge. In a mathematical sense, an undirected graph
consists of a set of vertices and a finite set of undirected edges, where each edge has
a set of one or two vertices associated with it. In the computer science view of
undirected graphs, though, an undirected graph is the particular case of a directed
graph in which for every edge (v, w) of the graph, the reversed edge (w, v) also
belongs to the graph. Undirected graphs are also called bidirected.

Definition 1.6 A graph G = (V, E) is undirected if (v, w) ∈ E implies (w, v) ∈ E,


for all v, w ∈ V .
1.1 Trees and Graphs 7

1 2 1 2

3 4 5 3 4 5

6 7 6 7

Fig. 1.5 The undirected graph underlying the graph of Fig. 1.1. The standard presentation is given
in the drawing to the left, while the understanding of undirected edges as pairs of counter-parallel
edges is emphasized in the drawing to the right

Undirected graphs are often drawn as a set of points in the plane and a set of line
segments, each of which joins two (not necessarily different) points. In a drawing of
an undirected graph G = (V, E), each vertex v ∈ V is drawn as a point or a small
circle and each pair of counter-parallel edges (v, w), (w, v) ∈ E is drawn as a line
segment between the points or circles corresponding to vertices v and w.

Example 1.6 The undirected graph underlying the graph of Fig. 1.1 is shown in
Fig. 1.5.

The terminology of directed graphs carries over to undirected graphs, although a


few differences deserve mention. First of all, since an edge in an undirected graph is
understood as a pair of counter-parallel edges in the corresponding bidirected graph,
the number of edges coming into a given vertex and the number of edges going out
of the vertex coincide and therefore, no distinction is made between the indegree and
the outdegree of a vertex. That is, the degree of a vertex in an undirected graph is
equal to the indegree and the outdegree of the vertex in the corresponding bidirected
graph. For the same reason, the size of an undirected graph is half the size of the
corresponding bidirected graph.

Definition 1.7 The degree of a vertex v in an undirected graph G = (V, E) is the


number of edges in G that are incident with v. The degree sequence of G is the
sequence of n non-negative integers obtained by arranging the vertex degrees in
non-decreasing order.

Example 1.7 There are three vertices of degree 2 in the graph of Fig. 1.6, two
vertices of degree 3, two vertices of degree 4, and two vertices of degree 5. The
degree sequence of the graph is [2, 2, 2, 3, 3, 4, 4, 5, 5].

A walk, trail, or path in an undirected graph is a walk, trail, or path, respectively,


in the corresponding bidirected graph. Another important graph-theoretical notion
is that of connected and disconnected graphs. An undirected graph is connected if
every pair of its vertices is joined by some walk, and an undirected graph that is
not connected is said to be disconnected. On the other hand, a graph is connected if
for all vertices v and w in the graph, there is a walk from v to w, and it is strongly
8 1 Introduction

Fig. 1.6 Undirected graph


with degree sequence
[2, 2, 2, 3, 3, 4, 4, 5, 5]

Fig. 1.7 A graph with five


strong components whose
underlying undirected graph
is connected

connected if there are walks from v to w and from w back to v, for all vertices v and
w in the graph.

Definition 1.8 An undirected graph G = (V, E) is connected if for every pair of


vertices v, w ∈ E, there is a walk between v and w. A graph is connected if the
underlying undirected graph is connected. Graph G is strongly connected if for
every pair of vertices v, w ∈ E, there are walks from v to w and from w to v.

Connectivity is an equivalence relation on the vertex set of a graph, which induces a


partition of the graph into subgraphs induced by connected vertices, called connected
components or just components.

Definition 1.9 A component of an undirected graph G is a connected subgraph of


G which is not properly contained in any other connected subgraph of G. A strong
component of a graph G is a strongly connected subgraph of G which is not properly
contained in any other strongly connected subgraph of G.

Example 1.8 The graph of Fig. 1.7 has five strong components, induced, respec-
tively, by the vertex sets {v1 , v4 , v5 , v8 }, {v2 }, {v3 }, {v6 , v7 , v10 }, and {v9 }. The under-
lying undirected graph is, however, connected.

Some common families of undirected graphs are the trees, the complete graphs,
the path graphs, the cycle graphs, the wheel graphs, the bipartite graphs, and the
regular graphs. A tree is a connected graph having no cycles.

Definition 1.10 An undirected graph G = (V, E) is said to be an undirected tree


if it is connected and has no cycles.

Example 1.9 The undirected trees with one, two, three, four, five, and six vertices
are shown in Fig. 1.8.
1.1 Trees and Graphs 9

Fig. 1.8 The first fourteen undirected trees

Fig. 1.9 The first six complete graphs

In a complete graph, every pair of distinct vertices is joined by an edge.

Definition 1.11 An undirected graph G = (V, E) is said to be a complete graph


if for all v, w ∈ V with v = w, (v, w) ∈ E. The complete graph on n vertices is
denoted by K n .

Example 1.10 The complete graphs on one, two, three, four, five, and six vertices
are shown in Fig. 1.9.

A path graph can be drawn such that all vertices lie on a straight line.

Definition 1.12 A connected undirected graph G = (V, E) with n = m + 1 is said


to be a path graph if it can be drawn such that all vertices lie on a straight line. The
path graph on n vertices is denoted by Pn .
10 1 Introduction

Fig. 1.10 The first six path graphs

Fig. 1.11 The first six cycle graphs

Example 1.11 The path graphs on one, two, three, four, five, and six vertices are
shown in Fig. 1.10.

A cycle graph can be drawn such that all vertices lie on a circle.

Definition 1.13 A connected undirected graph G = (V, E) with n = m is said to


be a cycle graph if it can be drawn such that all vertices lie on a circle. The cycle
graph on n vertices is denoted by Cn .

Example 1.12 The cycle graphs on one, two, three, four, five, and six vertices are
shown in Fig. 1.11.

A wheel graph has a distinguished (inner) vertex that is connected to all other
(outer) vertices, and it can be drawn such that all outer vertices lie on a circle centered
at the inner vertex.

Definition 1.14 A connected undirected graph G = (V, E) is said to be a wheel


graph if it can be drawn such that all but a single vertex lie on a circle centered at
the single vertex, which is connected to all other vertices. The wheel graph with n
outer vertices is denoted by Wn+1 .

Example 1.13 The wheel graphs with one, two, three, four, five, and six outer ver-
tices are shown in Fig. 1.12.

Another common family of undirected graphs is the bipartite graphs. The vertex
set of a bipartite graph can be partitioned into two subsets in such a way that every
1.1 Trees and Graphs 11

Fig. 1.12 The first six wheel graphs

Fig. 1.13 The first twelve complete bipartite graphs

edge of the graph joins a vertex of one subset with a vertex of the other subset. In
a complete bipartite graph, every vertex of one subset is joined by some edge with
every vertex of the other subset.

Definition 1.15 An undirected graph G = (V, E) is said to be a bipartite graph if


V can be partitioned into two disjoint subsets X and Y such that for all (x, y) ∈ E,
either x ∈ X and y ∈ Y , or x ∈ Y and y ∈ X , and it is said to be a complete
bipartite graph if, furthermore, (x, y), (y, x) ∈ E for all x ∈ X and y ∈ Y . The
complete bipartite graph on p + q vertices, where subset X has p vertices and subset
Y has q vertices, is denoted by K p,q .

Example 1.14 The complete bipartite graphs with two, three, four, five, six, and
seven vertices are shown in Fig. 1.13. The bipartite sets are distinguished by drawing
vertices either in red or in black. Then, every edge joins a red vertex with a black
vertex.
12 1 Introduction

Fig. 1.14 Maximal (left) and maximum (right) matching in a bipartite graph. Matchings are
shown highlighted. The matching {(x1 , y1 ), (x2 , y2 ), (x3 , y3 ), (x4 , y5 )} is not maximal, because
it is included in matching {(x1 , y1 ), (x2 , y2 ), (x3 , y3 ), (x4 , y5 ), (x5 , y6 )}, which is maximal but not
maximum. Matching {(x1 , y1 ), (x2 , y6 ), (x3 , y3 ), (x4 , y5 ), (x5 , y4 ), (x6 , y2 )} is maximal and also
a maximum matching

Fig. 1.15 Maximum cardinality (left) and maximum weight (right) matching in a bipartite graph
with weighted edges. Matchings are shown highlighted

Definition 1.16 Let G = (X ∪ Y, E) be a bipartite graph with E ⊆ X × Y and


X ∩ Y = ∅. A matching in G is a set of edges M ⊆ E such that x1 = x2 and
y1 = y2 for all distinct edges (x1 , y1 ), (x2 , y2 ) ∈ M. A matching M in a bipartite
graph G is maximal if there is no matching M  in G such that M ⊆ M  and M = M  ,
and it is maximum if there is no matching in G with more edges than M. Further, a
matching M in a bipartite graph G is perfect if |M| = min(|X |, |Y |).

Example 1.15 There are 577 non-trivial matchings in the bipartite graph of Fig. 1.14,
69 of which are maximal. The smallest one has four edges, and there are 22
of them, such as {(x1 , y1 ), (x2 , y2 ), (x4 , y3 ), (x5 , y5 )}. There are also 44 maximal
matchings with five edges, such as {(x1 , y1 ), (x2 , y2 ), (x3 , y3 ), (x4 , y5 ), (x5 , y6 )},
and three maximal matchings with six edges, which are also maximum matchings:
{(x1 , y1 ), (x2 , y2 ), (x3 , y3 ), (x4 , y6 ), (x5 , y4 ), (x6 , y5 )}, {(x1 , y1 ), (x2 , y6 ), (x3 , y2 ),
(x4 , y3 ), (x5 , y4 ), (x6 , y5 )}, which is shown to the right of the figure, and {(x1 , y1 ),
(x2 , y6 ), (x3 , y3 ), (x4 , y5 ), (x5 , y4 ), (x6 , y2 )}.

A maximum matching in a bipartite graph is also called a maximum cardinal-


ity bipartite matching, in order to distinguish it from a maximum weight bipartite
matching in a bipartite graph with weighted edges, where the weight of a matching
is the total weight of the edges in the matching.
1.1 Trees and Graphs 13

Fig. 1.16 Regular graphs G 1 and G 2 of same order and size

Example 1.16 In the bipartite graph of Fig. 1.15, {(x1 , y2 ), (x2 , y3 ), (x3 , y4 ),
(x4 , y1 )} is a maximum cardinality matching, with total edge weight 6, and {(x2 , y1 ),
(x3 , y2 ), (x4 , y4 )} is a maximum weight matching of weight 16.

A natural generalization of bipartite graphs is the k-partite graphs. The vertex set
of a k-partite graph can be partitioned into k subsets in such a way that every edge
of the graph joins a vertex of one subset with a vertex of another subset.

Definition 1.17 An undirected graph G = (V, E) is said to be a k-partite graph if


V can be partitioned into k  2 subsets V1 , V2 , . . . , Vk such that for all (v, w) ∈ E
with v ∈ Vi and w ∈ V j , it holds that i = j.

Complete graphs and cycle graphs are trivial examples of regular graphs. In a
regular graph, all vertices have the same degree.

Definition 1.18 An undirected graph G = (V, E) is said to be a regular graph if


deg(v) = deg(w) for all v, w ∈ V .

Example 1.17 The regular graphs G 1 and G 2 shown in Fig. 1.16 share the same
degree sequence, [2, 2, 2, 2, 2, 2].

Labeled Graphs

Most applications of graphs in computer science involve labeled graphs, where


vertices and edges have additional attributes such as color or weight. For a labeled
graph G = (V, E), the label of a vertex v ∈ V is denoted by label[v], and the label
of an edge (v, w) = e ∈ E is denoted by label[e] or just by label[v, w].

Example 1.18 An undirected graph of the geographical adjacencies between some


of the first European states to adopt the European currency is shown in Fig. 1.17.
Vertices represent European states and are labeled with a standard abbreviation for
the name of the state. There is an edge between two vertices if the corresponding
states share a border. Edges are labeled with the distance in kilometers between the
capital cities of the states they join.
14 1 Introduction

Fig. 1.17 A labeled undirected graph of geographical adjacencies between some European states

Fig. 1.18 An ordered undirected graph. The relative order of the vertices adjacent with a given
vertex reflects the counter-clockwise ordering of the outgoing edges of the vertex in the drawing

Ordered Graphs

An ordered graph is a graph in which the relative order of the adjacent vertices is
fixed for each vertex. Ordered graphs arise when a graph is drawn or embedded on
a certain surface, for instance, in the Euclidean plane.

Example 1.19 The relative order of the vertices adjacent with each of the vertices
of the ordered undirected graph shown in Fig. 1.18 reflects the counter-clockwise
ordering of the outgoing edges of the vertex in the drawing. For instance, the the
ordered sequence of vertices [v1 , v8 , v7 , v3 ] adjacent with vertex v2 reflects the
counter-clockwise ordering {v2 , v1 }, {v2 , v8 }, {v2 , v7 }, {v2 , v3 } of the edges incident
with vertex v2 in the drawing of the graph.

Trees

The families of undirected graphs introduced above have a directed graph counter-
part. In particular, while the notion of tree most often found in discrete mathematics
is that of an undirected tree, the notion of the tree which is most useful in computer
science is that of the rooted directed tree or just tree. A tree is the particular case of
a graph in which there is a distinguished vertex, called the root of the tree, such that
there is a unique walk from the root to any vertex of the tree. The vertices of a tree
are called nodes.
1.1 Trees and Graphs 15

Fig. 1.19 Graph T1 is not a rooted tree, although it is connected and has no cycles. Graph T2 is a
tree rooted at node v1

Definition 1.19 A connected graph G = (V, E) is said to be a tree if the underlying


undirected graph has no cycles and there is a distinguished node r ∈ V , called the
root of the tree and denoted by root[T ] such that for all nodes v ∈ V , there is a path
in G from the root r to node v.

Example 1.20 Two connected graphs are shown in Fig. 1.19. Graph T1 is not a tree
rooted at node u 1 , although the underlying undirected graph has no cycles. As a
matter of fact, there is no path in T1 from node u 1 to any of nodes u 7 , u 8 , and u 9 .
Graph T2 , on the other hand, is indeed a tree rooted at node v1 .

The existence of a unique path in a tree from the root to any other node imposes a
hierarchical structure in the tree. The root lies at the top, and nodes can be partitioned
in hierarchical levels according to their distance from the root of the tree.

Definition 1.20 Let T = (V, E) be a tree. The depth of node v ∈ V , denoted by


depth[v], is the length of the unique path from the root node root[T ] to node v, for all
nodes v ∈ V . The depth of T is the maximum among the depth of all nodes v ∈ V .

The hierarchical structure embodied in a tree leads to further distinguishing among


the nodes of the tree: parent nodes are joined by edges to their children nodes, nodes
sharing the same parent are called sibling, and nodes having no children are called
leaves.

Definition 1.21 Let T = (V, E) be a tree. Node v ∈ V is said to be the parent of


node w ∈ V , denoted by parent[w], if (v, w) ∈ E and, in such a case, node w is said
to be a child of node v. The children of node v ∈ V are the set of nodes W ⊆ V such
that (v, w) ∈ E for all w ∈ W . A node having no children is said to be a leaf node.
Non-root nodes v, w ∈ V are said to be sibling nodes if parent[v] = parent[w]. The
number of children of node v ∈ V is denoted by children[v]. The tree is said to be a
binary tree if |children[v]|  2 for every node v ∈ V , and a complete binary tree
if, furthermore, it has n/2 non-leaf nodes, where n = |V |, and at most one node
v ∈ V with |children[v]| = 1, whose only child is a leaf node.
16 1 Introduction

Example 1.21 In tree T2 of Fig. 1.19, node v2 is the parent of node v5 , and v8 , v9
are sibling nodes, because they are both children of node v7 . The root of T2 is node
v1 , and the leaves are v3 , v4 , v5 , v8 , v9 , v10 , v12 , v13 . Nodes v2 , v6 , v7 , v11 are neither
root nor leaf nodes.

The reader may prefer to consider the hierarchical structure of a tree the other way
around, though. The leaves constitute the first level of height zero, their parents form
the second level of height one, and so on. In other words, nodes can be partitioned
in levels according to their height.

Definition 1.22 Let T = (V, E) be a tree. The height of node v ∈ V , denoted by


height[v], is the length of a longest path from node v to any node in the subtree of T
rooted at node v, for all nodes v ∈ V . The height of T is the maximum among the
height of all nodes v ∈ V .

It follows from Definition 1.20 that in a tree T = (V, E), depth[v]  0 for all
nodes v ∈ V , and that depth[v] = 0 if and only if v = root[T ]. Further, it follows
from Definition 1.22 that height[v]  0 for all nodes v ∈ V , and that height[v] = 0
if and only if v is a leaf node.

Example 1.22 In the tree shown twice in Fig. 1.20, node v1 is the root and has
depth zero and height three, which is also the height of the tree. Node v2 has depth
and height one; nodes v3 , v4 , v5 , v10 have depth two and height zero; node v6 has
depth one and height two; nodes v7 , v11 have depth two and height one; and nodes
v8 , v9 , v12 , v13 have depth three, which is also the depth of the tree, and height zero,
which is the height of all the leaves in the tree.

Trees are, indeed, the least connected graphs. The number of edges in a tree is
one less than the number of nodes in the tree.

Theorem 1.2 Let T = (V, E) be a tree. Then m = n − 1.

Fig. 1.20 The tree of Fig. 1.19 is shown twice, emphasizing the depth (left) and the height (right)
of all nodes in the tree
1.1 Trees and Graphs 17

Proof By induction on the number of nodes n in the tree. For n = 1, a tree with one
node has no edges, that is, m = 0. Assume, then, that every tree with n  1 nodes
has n − 1 edges.
Let T = (V, E) be a tree with n + 1 nodes, and let v ∈ V be any leaf node of T .
The subgraph of T induced by V \ {v} is a tree with n nodes and has, by induction
hypothesis, n − 1 edges. Now, since there is only one edge (w, v) ∈ E (namely, with
w the parent in T of node v), it follows that the subgraph of T induced by V \ {v}
has one edge less than T . Therefore, T has n + 1 nodes and n edges. 

As with graphs, there is also a basic relationship between the number of nodes in
a tree and the number of children of the nodes of the tree, which will prove to be
very useful in analyzing the computational complexity of algorithms on trees.

Lemma 1.1 Let T = (V, E) be a tree on n nodes, and let V = {v1 , . . . , vn }. Then,
n
children[vi ] = n − 1 .
i=1

Proof Let T = (V, E) be a tree. Since every non-root node w ∈ V is the target
n
of
n a different edge (v, w) ∈ E, it holds by Theorem
n 1.1 that i=1 children[vi ] =
i=1 outdeg(vi ) = m and then, by Theorem 1.2, i=1 children[vi ] = n − 1. 

Now, given that trees are a particular case of graphs, it is natural to consider trees
as subgraphs of a given graph and, as a matter of fact, those trees that span all the
vertices of a graph arise in several graph algorithms. A spanning tree of a graph is a
subgraph that contains all the vertices of the graph and is a tree.

Definition 1.23 Let G = (V, E) be a graph. A subgraph (W, S) of G is a spanning


tree of graph G if W = V and (W, S) is a tree.

Example
6 1.23 The graph of Fig. 1.21 has n = 4 vertices and m = 6 edges, and thus
3 = 20 subgraphs with 4 vertices and 3 edges. However, only 6 of these subgraphs
are trees. These spanning trees of the graph are shown highlighted.

Fig. 1.21 Spanning trees of a graph


18 1 Introduction

Fig. 1.22 Spanning forests of a graph

Fig. 1.23 An ordered tree.


The relative order of the
children of a given node
reflects the
counter-clockwise ordering
of the outgoing edges of the
node in the drawing

Not every graph has a spanning tree, though, but every graph has a spanning
forest, that is, an ordered set of pairwise-disjoint subgraphs that are trees and which,
together, span all the vertices of the graph.

Definition 1.24 Let G = (V, E) be a graph. A sequence [(W1 , S1 ), . . . , (Wk , Sk )]


of k  1 subgraphs of G is a spanning forest of graph G if W1 ∪ · · · ∪ Wk = V ;
Wi ∩ W j = ∅ for all 1  i, j  k with i = j; and (Wi , Si ) is a tree, for all 1  i  k.

Example 1.24 The graph of Fig. 1.22 has no spanning tree, but there are 12 forests
that span all the vertices of the graph. These spanning forests of the graph are shown
highlighted, up to a permutation of the sequence of trees in a forest. Consider, for
instance, trees T1 = ({v1 }, ∅) and T2 = ({v2 , v3 , v4 }, {(v2 , v3 ), (v2 , v4 )}). Spanning
forests [T1 , T2 ] and [T2 , T1 ] are both highlighted together, at the left of the top row.

Ordered Trees

An ordered tree is a tree in which the relative order of the children is fixed for each
node. As a particular case of ordered graphs, ordered trees arise when a tree is drawn
or embedded in the Euclidean plane.

Example 1.25 In the ordered tree shown in Fig. 1.23, the children of node v1
are [v2 , v6 ]; the children of node v2 are [v3 , v4 , v5 ]; the children of node v6 are
1.1 Trees and Graphs 19

[v7 , v10 , v11 ]; the children of node v7 are [v8 , v9 ]; and the children of node v11 are
[v12 , v13 ]. The remaining nodes have no children. The relative order of the children
of each of the nodes reflects the counter-clockwise ordering of the outgoing edges of
the node in the drawing. For instance, the ordered sequence [v7 , v10 , v11 ] of the chil-
dren of node v6 reflects the counter-clockwise ordering (v6 , v7 ), (v6 , v10 ), (v6 , v11 )
of the edges going out of node v6 in the drawing of the ordered tree.

The relative order of children nodes leads to further distinguishing among the
nodes of an ordered tree: children nodes are ordered from the first up to the last,
non-first children nodes have a previous sibling, and non-last children nodes have a
next sibling. For sibling nodes v and w, let v < w denote that v precedes w in the
ordered tree.

Definition 1.25 Let T = (V, E) be an ordered tree, and let (v, w) ∈ E. Node w ∈ V
is said to be the first child of node v ∈ V , denoted by first[v], if there is no node
z ∈ V such that (v, z) ∈ E and z < w. Node w ∈ V is said to be the last child
of node v ∈ V , denoted by last[v], if there is no node z ∈ V such that (v, z) ∈ E
and w < z. Node z ∈ V is said to be the next sibling of node w ∈ V , denoted by
next[w], if (v, z) ∈ E, w < z, and there is no node x ∈ V such that (v, x) ∈ E and
w < x < z. Node w ∈ V is said to be the previous sibling of node z ∈ V , denoted
by previous[z], if next[w] = z.

Example 1.26 In the ordered tree shown in Fig. 1.23, first[v6 ] = v7 , last[v6 ] = v11 ,
and next[v7 ] = v10 = previous[v11 ].

1.2 Basic Data Structures

Some of the basic data structures needed for the description of algorithms on trees and
graphs are illustrated below using a fragment of pseudocode. Pseudocode conven-
tions follow modern programming guidelines, such as avoiding global side effects
(with the only exception of object attributes, which are hidden behind dot-notation)
and the unconditional transfer of control by way of goto or gosub statements.

• Assignment of value a to variable x is denoted by x ← a.


• Comparison of equality between the values of two variables x and y is denoted
by x = y; comparison of strict inequality is denoted by either x = y, x < y,
or x > y; and comparison of non-strict inequality is denoted by either x  y or
x  y.
• Logical true and false are denoted by true and false, respectively.
• Logical negation, conjunction, and disjunction are denoted by not, and, and or,
respectively.
• Non-existence is denoted by nil.
20 1 Introduction

• Mathematical notation is preferred over programming notation. For example, the


cardinality of a set S is denoted by |S|, membership of an element x in a set S is
denoted by x ∈ S, insertion of an element x into a set S is denoted by S ← S ∪{x},
and deletion of an element x from a set S is denoted by S ← S \ {x}.
• Control structures use the following reserved words: all, break, do, else, for, if,
repeat, return, then, to, until, and while.
• Blocks of statements are shown by means of indention.

if … then for all … do while … do repeat


… … … …
else … if … then …
… return … … until …

The collection of abstract operations on arrays, matrices, lists, stacks, queues,


priority queues, sets, and dictionaries is presented next by way of examples.

Arrays

An array is a one-dimensional array indexed by non-negative integers. The [i]


operation returns the i-th element of the array, assuming there is such an element.

let A[1..n] be a new array


for i = 1 to n do
A[i] ← false

Matrices

A matrix is a two-dimensional array indexed by non-negative integers. The [i, j]


operation returns the element in the i-th row and the j-th column of the matrix,
assuming there is such an element.

let M[1..m][1..n] be a new matrix


for i = 1 to m do
for j = 1 to n do
A[i, j] ← 0
1.2 Basic Data Structures 21

Lists

A list is just a sequence of elements. The front operation returns the first element
and the back operation returns the last element in the list, assuming the list is not
empty. The prev operation returns the element before a given element in the list,
assuming the given element is not at the front of the list. The next operation returns
the element after a given element in the list, assuming the given element is not at
the back of the list. The append operation inserts an element at the rear of the list.
The concatenate operation deletes the elements of another list and inserts them at
the rear of the list.

let L be an empty list


append x to L L .append(x)
let L  be an empty list
append x to L 
concatenate L  to L L .concatenate(L  )
let x be the element at the front of L x ← L .front()
while x = nil do
output x
x ← L .next(x)
let x be the element at the back of L x ← L .back()
while x = nil do
output x
x ← L .prev(x)

Stacks

A stack is a sequence of elements that are inserted and deleted at the same end (the
top) of the sequence. The top operation returns the top element in the stack, assuming
the stack is not empty. The pop operation deletes and returns the top element in the
stack, also assuming the stack is not empty. The push operation inserts an element
at the top of the stack.

let S be an empty stack


push x onto S S.push(x)
let x be the element at the top of S x ← S.top()
output x
while S is not empty do ¬S.empty()
pop from S the top element x x ← S.pop()
output x
22 1 Introduction

Queues

A queue is a sequence of elements that are inserted at one end (the rear) and deleted
at the other end (the front) of the sequence. The front operation returns the front
element in the queue, assuming the queue is not empty. The dequeue operation
deletes and returns the front element in the queue, assuming the queue is not empty.
The enqueue operation inserts an element at the rear end of the queue.

let Q be an empty queue


enqueue x into Q Q.enqueue(x)
let x be the element at the front of Q x ← Q.front()
output x
repeat
dequeue from Q the front element x x ← Q.dequeue()
output x
until Q is empty Q.empty()

Priority Queues

A priority queue is a queue of elements with both an information and a priority


associated with each element, where there is a linear order defined on the priorities.
The front operation returns an element with the minimum priority, assuming the
priority queue is not empty. The dequeue operation deletes and returns an element
with the minimum priority in the queue, assuming the priority queue is not empty.
The enqueue operation inserts an element with a given priority in the priority queue.

let Q be an empty priority queue


enqueue (x, y) into Q Q.enqueue(x, y)
let (x, y) be an element x
with the minimum priority y in Q (x, y) ← Q.front()
output (x, y)
repeat
dequeue from Q an element x
with the minimum priority y (x, y) ← Q.dequeue()
output (x, y)
until Q is empty Q.empty()
1.2 Basic Data Structures 23

Sets

A set is just a set of elements. The insert operation inserts an element in the set. The
delete operation deletes an element from the set. The member operation returns true
if an element belongs to the set and false otherwise.

let S be an empty set


S = S ∪ {x} S.insert(x)
for all x ∈ S do S.member(x)
output x
delete x from S S.delete(x)

Dictionaries

A dictionary is an associative container, consisting of a set of elements with both an


information and a unique key associated with each element, where there is a linear
order defined on the keys and the information associated with an element is retrieved
on the basis of its key. The member operation returns true if there is an element
with a given key in the dictionary, and false otherwise. The lookup operation returns
the element with a given key in the dictionary, or nil if there is no such element.
The insert operation inserts and returns an element with a given key and given
information in the dictionary, replacing the element (if any) with the given key. The
delete operation deletes the element with a given key from the dictionary if there is
such an element.

let D be an empty dictionary


D[x] ← y D.insert(x, y)
for all x ∈ D do D.member(x)
y ← D[x] y ← D.lookup(x)
output (x, y)
delete x from D D.delete(x)

1.3 Representation of Trees and Graphs

There are several different ways in which graphs and, in particular, trees can be
represented in a computer, and the choice of a data structure often depends on the
efficiency with which the operations that access and update the data need to be
supported. As a matter of fact, there is often a tradeoff between the space complexity
of a data structure and the time complexity of the operations.
24 1 Introduction

Representation of Graphs

A graph representation consists of a collection of abstract operations, a concrete


representation of graphs by appropriate data structures, and an implementation of
the abstract operations using the concrete data structures.
The choice of abstract operations to be included in a graph representation depends
on the particular application area. For instance, the representation of graphs in the
LEDA library of efficient data structures and algorithms [43] supports about 120 dif-
ferent operations, roughly half of which address the needs of computational geom-
etry algorithms, and the representation of graphs in the BGL library of graph algo-
rithms [55] supports about 50 different operations. The following collection of 32
abstract operations, though, covers the needs of most of the algorithms on graphs
presented in this book.

• G.vertices() and G.edges() give, respectively, a list of the vertices and a list of the
edges of graph G in the order fixed by the representation of G.
• G.incoming(v) and G.outgoing(v) give a list of the edges of graph G coming into
and going out of vertex v, respectively, in the order fixed by the representation
of G.
• G.number_of_vertices() and G.number_of_edges() give, respectively, the order n
and the size m of graph G.
• G.indeg(v) and G.outdeg(v) give, respectively, the number of edges coming into
and going out of vertex v in graph G.
• G.adjacent(v, w) is true if there is an edge in graph G going out of vertex v and
coming into vertex w, and false otherwise.
• G.source(e) and G.target(e) give, respectively, the source and the target vertex of
edge e in graph G.
• G.opposite(v, e) gives G.target(e) if vertex v is the source of edge e in graph G,
and G.source(e) otherwise.
• G.first_vertex() and G.last_vertex() give, respectively, the first and the last vertex
in the representation of graph G. Further, G.pred_vertex(v) and
G.succ_vertex(v) give, respectively, the predecessor and the successor of vertex
v in the representation of graph G. These operations support iteration over the
vertices of the graph.
• G.first_edge() and G.last_edge() give, respectively, the first and the last edge in
the representation of graph G. Further, G.pred_edge(e) and G.succ_edge(e) give,
respectively, the predecessor and the successor of edge e in the representation of
graph G. These operations support iteration over the edges of the graph.
• G.first_in_edge(v) and G.last_in_edge(v) give, respectively, the first and the last
edge in the representation of graph G coming into vertex v. Further, G.in_pred(e)
and G.in_succ(e) give, respectively, the previous and the next edge after e in
the representation of graph G coming into vertex G.target(e). These operations
support iteration over the vertices of the graph adjacent with a given vertex.
1.3 Representation of Trees and Graphs 25

• G.first_adj_edge(v) and G.last_adj_edge(v) give, respectively, the first and the last
edge in the representation of graph G going out of vertex v. Further, G.adj_pred(e)
and G.adj_succ(e) give, respectively, the previous and the next edge after e in the
representation of graph G going out of vertex G.source(e). These operations also
support iteration over the vertices of the graph adjacent with a given vertex.
• G.new_vertex() inserts a new vertex in graph G, and G.new_edge(v, w) inserts
a new edge in graph G going out of vertex v and coming into vertex w. Further,
G.del_vertex(v) deletes vertex v from graph G, together with all those edges going
out of or coming into vertex v, and G.del_edge(e) deletes edge e from graph G.
These operations support dynamic graphs.

Notice that some of these operations are actually defined in terms of a smaller set
of 10 abstract operations on graphs,

• G.vertices() • G.target(e)
• G.edges() • G.new_vertex()
• G.incoming(v) • G.new_edge(v, w)
• G.outgoing(v) • G.del_vertex(v)
• G.source(e) • G.del_edge(e)

using the abstract operations on basic data structures presented in Sect. 1.2, as fol-
lows:
• G.number_of_vertices() is given by G.vertices().size().
• G.number_of_edges() is given by G.edges().size().
• G.indeg(v) is given by G.incoming(v).size().
• G.outdeg(v) is given by G.outgoing(v).size().
• G.adjacent(v, w) is true if there is an edge e ∈ G.outgoing(v) such that G.target(e) =
w, and it is false otherwise.
• G.opposite(v, e) is given by G.target(e) if G.source(e) = v, and it is given by
G.source(e) otherwise, that is, if G.target(e) = v.
• G.first_vertex() is given by G.vertices().front().
• G.last_vertex() is given by G.vertices().back().
• G.pred_vertex(v) is given by G.vertices().prev(v).
• G.succ_vertex(v) is given by G.vertices().next(v).
• G.first_edge() is given by G.edges().front().
• G.last_edge() is given by G.edges().back().
• G.pred_edge(e) is given by G.edges().prev(e).
• G.succ_edge(e) is given by G.edges().next(e).
• G.first_in_edge(v) is given by G.incoming(v).front().
• G.last_in_edge(v) is given by G.incoming(v).back().
• G.in_pred(e) is given by G.incoming(v).prev(e).
• G.in_succ(e) is given by G.incoming(v).next(e).
• G.first_adj_edge(v) is given by G.outgoing(v).front().
26 1 Introduction

• G.last_adj_edge(v) is given by G.outgoing(v).back().


• G.adj_pred(e) is given by G.outgoing(v).prev(e).
• G.adj_succ(e) is given by G.outgoing(v).next(e).

Together with the abstract operations on the underlying basic data structures, these
operations support iteration over the vertices and edges of a graph. For instance, in
the following procedure, variable v is assigned each of the vertices of graph G in
turn,

for all vertices v of G do v ∈ G.vertices()


and in the following procedure, all those vertices of graph G which are adjacent with
vertex v are assigned in turn to variable w.

for all vertices w adjacent with vertex v in G do e ∈ G.outgoing(v)


… w = G.target(e)

Together, they provide for a simple traversal of a graph, in which vertices and
edges are visited in the order fixed by the representation of the graph.

for all vertices v of G do v ∈ G.vertices()


for all vertices w adjacent with vertex v in G do e ∈ G.outgoing(v)
… w = G.target(e)

Adjacency Matrix

The data structures most often used for representing graphs are adjacency matrices
and adjacency lists. The adjacency matrix representation of a graph is a Boolean
matrix, with an entry for each ordered pair of vertices in the graph, where the entry
corresponding to vertices v and w has the value true if there is an edge in the graph
going out of vertex v and coming into vertex w, and it has the value false otherwise.

Definition 1.26 Let G = (V, E) be a graph with n vertices. The adjacency matrix
representation of G is an n × n Boolean matrix with an entry for each ordered pair
of vertices of G, where the entry corresponding to vertices v and w is equal to true
if (v, w) ∈ E and is equal to false otherwise, for all vertices v, w ∈ V .

Example 1.27 The adjacency matrix representation of the graph of Fig. 1.1 is shown
in Fig. 1.24. Entries equal to true are denoted by 1, and false entries are denoted by 0.
1.3 Representation of Trees and Graphs 27

Fig. 1.24 Adjacency matrix representation of the graph of Fig. 1.1

Notice that with most data structures used for representing graphs, there is an
order on the vertices fixed by the representation. In the case of the adjacency
matrix representation A of a graph G = (V, E), vertex v precedes vertex w
if and only if the row of A corresponding to v lies above the row of A cor-
responding to w or, in an equivalent formulation, the column of A correspond-
ing to v lies to the left of the column of A corresponding to w, for all vertices
v, w ∈ V .
Now, since the edges are implicit in the adjacency matrix representation of a
graph, those operations having an edge as argument or giving an edge as result
cannot be implemented using an adjacency matrix representation. These opera-
tions are: G.edges(), G.incoming(v), G.outgoing(v), G.source(e), G.target(e), and
G.del_edge(e). Furthermore, G.new_vertex() and G.del_vertex(v) cannot be imple-
mented unless the adjacency matrix can be dynamically resized, and G.new_edge(v, w)
can be implemented by setting to true the entry of A at the row corresponding to
vertex v and the column corresponding to vertex w, and takes O(1) time, but the
operation cannot give the new edge as result.
Let G = (V, E) be a graph with n vertices, let us assume the vertices are numbered
1, 2, . . . , n in some arbitrary manner and their number is stored in the attribute index,
and let A be the adjacency matrix representation of G. The only remaining operation,
G.vertices(), is just the sequence of all vertices v ∈ V ordered by the index attribute.
The adjacency matrix representation of a graph G = (V, E) with n vertices takes
(n 2 ) space. Therefore, no graph algorithm can be implemented using an adjacency
matrix representation to run in O(n) time. The main advantage of the adjacency
matrix representation is the support of the adjacency test in O(1) time.

Adjacency List

The adjacency list representation of a graph, on the other hand, is an array of lists,
one for each vertex in the graph, where the list corresponding to vertex v contains
the target vertices of the edges coming out of vertex v.
28 1 Introduction

Fig. 1.25 Adjacency list


representation of the graph
of Fig. 1.1. Lists of adjacent
vertices are shown as
sequences

Definition 1.27 Let G = (V, E) be a graph with n vertices and m edges. The
adjacency list representation of G consists of a list of n elements (the vertices of
the graph) and a list of n lists with a total of m elements (the target vertices for the
edges of the graph). The list corresponding to vertex v contains all vertices w ∈ V
with (v, w) ∈ E, for all vertices v ∈ V .

Notice that adjacency lists are not necessarily arranged in any particular order
although there is, as a matter of fact, an order on the vertices and edges fixed by the
adjacency list representation of the graph. Given the adjacency list representation of
a graph G = (V, E), vertex precedence is given by the order of the corresponding
entries in the list of lists, and edge (v, w) precedes edge (v, z) if and only if vertex w
precedes vertex z in the list corresponding to vertex v, for all edges (v, w), (v, z) ∈ E.

Example 1.28 The adjacency list representation of the graph of Fig. 1.1 is shown in
simplified form in Fig. 1.25, where lists of adjacent vertices are shown as sequences.

As in the case of adjacency matrices, edges are implicit in the adjacency list rep-
resentation of a graph, and those operations having an edge as argument or giving an
edge as result cannot be implemented using an adjacency list representation. These
operations are: G.edges(), G.incoming(v), G.outgoing(v), G.source(e), G.target(e),
and
G.del_edge(e). Furthermore, G.new_vertex() and G.del_vertex(v) cannot be imple-
mented unless the list of lists can be dynamically resized, and G.new_edge(v, w) can
be implemented by appending vertex w to the list corresponding to vertex v, and takes
O(1) time, but the operation cannot give the new edge as result. The only remaining
operation, G.adjacent(v, w), can be implemented by scanning the list corresponding
to vertex v and takes O(outdeg(v)) time.
The adjacency list representation of a graph G = (V, E) with n vertices and m
edges takes (n + m) space. Beside the low space requirement, the main advan-
tage of the adjacency list representation is the support of iteration operations in
O(1) time. Their main disadvantage, though, lies in the fact that an adjacency test
G.adjacent(v, w) is not supported in O(1) time but in O(outdeg(v)) time.
Notice that the adjacency matrix representation of a graph can be easily obtained
from the adjacency list representation, assuming the vertices are numbered 1, 2, . . . , n
in some arbitrary manner and their number is stored in attribute index. The following
1.3 Representation of Trees and Graphs 29

procedure makes A the adjacency matrix of graph G and runs in O(n 2 +m) = O(n 2 )
time.

let A[1..n][1..n] be a new matrix


for i = 1 to n do
for j = 1 to n do
A[i, j] ← false
for all edges e of G do
A[G.source(e).index, G.target(e).index] ← true

Then, implementing the adjacency test using the adjacency matrix representation
of a graph is straightforward. The following function adjacent(A, v, w) returns true
if (v, w) ∈ E and false otherwise and, given the adjacency matrix representation A
of the graph, runs in O(outdeg(v)) time.

function adjacent(A, v, w)
return A[v.index, w.index]

An alternative implementation of the adjacency test consists of scanning adjacent


vertices in the adjacency list representation. Let G = (V, E) be a graph, and let
v, w ∈ V . The following function adjacent(v, w) returns true if (v, w) ∈ E, and
false otherwise, and runs in O(outdeg(v)) time.

function adjacent(v, w)
for all vertices x adjacent with vertex v in G do
if x = w then
return true
return false

Extended Adjacency List

The adjacency list representation can be extended by making edges explicit. The
extended adjacency list representation of a graph consists of a list of vertices and
a list of edges. Associated with each vertex are two lists of incoming and outgoing
edges. Associated with each edge are its source and target vertices.

Definition 1.28 Let G = (V, E) be a graph with n vertices and m edges. The
extended adjacency list representation of G consists of a list of n elements (the
vertices of the graph), a list of m elements (the edges of the graph), and two lists of n
lists of a total of m elements (the edges of the graph). The incoming list corresponding
30 1 Introduction

Fig. 1.26 Extended


adjacency list representation
for the graph of Fig. 1.1.
Lists of incoming and
outgoing edges are shown as
sequences

to vertex v contains all edges (u, v) ∈ E coming into vertex v, for all vertices v ∈ V .
The outgoing list corresponding to vertex v contains all edges (v, w) ∈ E going out
of vertex v, for all vertices v ∈ V . The source vertex v and the target vertex w are
associated with each edge (v, w) ∈ E.

Example 1.29 The extended adjacency list representation of the graph of Fig. 1.1 is
shown in a simplified form in Fig. 1.26, where lists of incoming and outgoing edges
are shown as sequences.

Notice that edges are explicit in the extended adjacency list graph representation.
Therefore, all of the previous operations can be implemented using the extended adja-
cency list representation and take O(1) time, with the exception of G.del_node(v),
which takes O(deg(v)) time. The operations can be implemented as follows:

• G.vertices() and G.edges() are, respectively, the list of vertices and the list of
edges of graph G.
• G.incoming(v) and G.outgoing(v) are, respectively, the list of edges coming into
vertex v and the list of edges going out of vertex v.
• G.source(e) and G.target(e) are, respectively, the source and the target vertex
associated with edge e.
• G.new_vertex() is implemented by appending a new vertex v to the list of vertices
of graph G and returning vertex v.
• G.new_edge(v, w) is implemented by appending a new edge e to the list of edges
of graph G, setting to v the source vertex associated with edge e, setting to w the
target vertex associated with edge e, appending e to the list of edges going out of
vertex v and to the list of edges coming into vertex w, and returning edge e.
• G.del_vertex(v) is implemented by performing G.del_edge(e) for each edge e in
the list of edges coming into vertex v and for each edge e in the list of edges going
out of vertex v and then deleting vertex v from the list of vertices of graph G.
1.3 Representation of Trees and Graphs 31

• G.del_edge(e) is implemented by deleting edge e from the list of edges of graph G,


from the list of edges coming into vertex G.target(e), and from the list of edges
going out of vertex G.source(e).

The extended adjacency list representation of a graph G = (V, E) with n vertices


and m edges takes (n + m) space.

Adjacency Map

The adjacency list representation can also be extended by making edges explicit in
a different way. The lists of incoming and outgoing edges can be replaced with dic-
tionaries of source vertices to incoming edges and target vertices to outgoing edges.
This allows for a more efficient adjacency test, although adding a logarithmic factor
to the cost to all of the operations (when dictionaries are implemented using balanced
trees) or turning the worst-case cost for all of the operations into the expected cost
(when dictionaries are implemented using hashing).
The adjacency map representation of a graph consists of a dictionary D of vertices
to a pair of dictionaries of vertices to edges: a first dictionary I of source vertices to
incoming edges, and a second dictionary O of target vertices to outgoing edges.

Definition 1.29 Let G = (V, E) be a graph with n vertices and m edges. The adja-
cency map representation of G consists of a dictionary of n elements (the vertices
of the graph) to a pair of dictionaries of m elements (the source and target vertices
for the edges of the graph, respectively). The incoming dictionary corresponding
to vertex v contains the mappings (u, (u, v)) for all edges (u, v) ∈ E coming into
vertex v, for all vertices v ∈ V . The outgoing dictionary corresponding to vertex v
contains the mappings (v, (v, w)) for all edges (v, w) ∈ E going out of vertex v, for
all vertices v ∈ V .

Example 1.30 The adjacency map representation of the graph of Fig. 1.1 is shown
in simplified form in Fig. 1.27, where dictionaries are shown as sequences of vertex-
edge mappings.

Fig. 1.27 Adjacency map representation for the graph of Fig. 1.1. Dictionaries are shown as
sequences of vertex-edge mappings
32 1 Introduction

Notice that both vertices and edges are explicit in the adjacency map representation
of a graph. The vertices are the keys of the dictionary. The edges are the values in
the dictionary of outgoing edges, and also the values in the dictionary of incoming
edges, for all vertices of the graph. Therefore, all of the previous abstract operations
can be implemented using the adjacency map representation and take expected O(1)
time, with the exception of G.del_vertex(v), which takes O(deg(v)) expected time.
The operations can be implemented as follows:

• G.vertices() are the keys in dictionary D.


• G.edges() are the values D[v].O[w] for all keys v in dictionary D and for all keys
w in dictionary D[v].O.
• G.incoming(v) are the values D[v].I [u] for all keys u in dictionary D[v].I .
• G.outgoing(v) are the values D[v].O[w] for all keys w in dictionary D[v].O.
• G.source(e) and G.target(e) are, respectively, the source and the target vertex
associated with edge e.
• G.new_vertex() is implemented by inserting an entry in dictionary D, with key
a new vertex v and value a pair of empty dictionaries D[v].I and D[v].O, and
returning vertex v.
• G.new_edge(v, w) is implemented by setting to v the source vertex associated with
a new edge e, setting to w the target vertex associated with edge e, inserting an
entry in dictionary D[v].O with key w and value e, inserting an entry in dictionary
D[w].I with key v and value e, and returning edge e.
• G.del_vertex(v) is implemented by performing G.del_edge(e) for each entry with
key u and value e in dictionary D[v].I and for each entry with key w and value e
in dictionary D[v].O and then deleting the entry with key v from dictionary D.
• G.del_edge(e) is implemented by deleting the entry with key w from dictionary
D[v].O and deleting the entry with key v from dictionary D[w].I , where v =
G.source(e) and w = G.target(e).

Recall that the adjacency test G.adjacent(v, w) can be defined in terms of the
small set of abstract operations on graphs, using the abstract operations on basic data
structures, by scanning the list of outgoing edges G.outgoing(v) for an edge e such
that G.target(e) = w. Now, besides the low space requirement, the main advantage
of the adjacency map representation is the support of adjacency test in expected O(1)
time, when dictionaries are implemented using hashing, as follows:

• G.adjacent(v, w) is true if (w, e) ∈ D[v].O (where e = D[v].O[w]), and false


otherwise.

The adjacency map representation of a graph G = (V, E) with n vertices and m


edges takes (n + m) space.
1.3 Representation of Trees and Graphs 33

Representation of Trees

As in the case of graphs, a tree representation consists of a collection of abstract


operations, a concrete representation of trees by appropriate data structures, and
implementation of the abstract operations using the concrete data structures.
The following collection of 13 abstract operations covers the needs of most of the
algorithms on trees presented in this book.

• T.number_of_nodes() gives the number of nodes |V | of tree T = (V, E).


• T.root() gives root[T ].
• T.is_root(v) is true if node v = root[T ], and false otherwise.
• T.number_of_children(v) gives children[v], that is, the number of nodes w ∈ V
such that (v, w) ∈ E.
• T.parent(v) gives parent[v], that is, the parent in T of node v.
• T.children(v) gives a list of the children of node v in T .
• T.is_leaf(v) is true if node v is a leaf of T , and false otherwise.
• T.first_child(v) and T.last_child(v) give, respectively, the first and the last of
the children of node v, according to the order on the children of v fixed by the
representation of T , or nil if v is a leaf node of T .
• T.previous_sibling(v) and T.next_sibling(v) give, respectively, the previous child
of T.parent(v) before vertex v and the next child of T.parent(v) after vertex v,
according to the order on the children of T.parent(v) fixed by the representation
of T , or nil if v is a first child or a last child, respectively.
• T.is_first_child(v) and T.is_last_child(v) are true if node v is, respectively, the
first and the last of the children of node T.parent(v), according to the order on the
children of T.parent(v) fixed by the representation of T , and false otherwise.

The previous operations support iteration over the children of a node in a tree,
much in the same way that the graph operations support iteration over the vertices
and edges of a graph. In the following procedure, the children of node v in tree T
are assigned in turn to variable w.

let w be the first child of node v in T w = T.first_child(v)


while w = nil do
process node w
let w be the next sibling of node w in T w = T.next_sibling(w)

The following procedure is an alternative form of iteration over the children w of


a node v in a tree T .

if v is not a leaf node of T then ¬T.is_leaf(v)


34 1 Introduction

let w be the first child of node v in T w = T.first_child(v)


process node w
while w is not the last child of node v in T do w = T.last_child(v)
let w be the next sibling of node w in T w = T.next_sibling(w)
process node w

The following procedure is still another, more compact form of iteration over the
children w of a node v in a tree T .

for all children w of node v in T do w ∈ T.children(v)


process node w

Array of Parents

The data structures most often used for representing trees are the array-of-parents
representation and the first-child, next-sibling representation. The array-of-parents
representation of a tree is an array of nodes, with an entry for each node in the tree,
where the entry corresponding to node v has the value parent[v] if v is not the root
of the tree, and it has the value nil otherwise.

Definition 1.30 Let T = (V, E) be a tree with n nodes. The array-of-parents


representation of T is an array P of n nodes, indexed by the nodes of the tree, where
P[v] = parent[v] if v = root[T ], and P[v] = nil otherwise, for all nodes v ∈ V .

Fig. 1.28 Array-of-parents representation of a tree


1.3 Representation of Trees and Graphs 35

Example 1.31 The array-of-parents representation P of the tree T = (V, E) of


Fig. 1.23 is shown in Fig. 1.28. The parent of node v is given by P[v], for all nodes
v ∈ V.

The array of parent nodes is not necessarily arranged in any particular order
although there is, as a matter of fact, an order on the nodes fixed by the representation.
Given the array-of-parents representation of a tree, node precedence is given by the
order of the nodes as array indices, and precedence between sibling nodes is also
given by the order of array indices.
Let T = (V, E) be a tree with n nodes, and let P be the array-of-parents
representation of T . Operations T.root(), T.number_of_children(v), T.children(v),
T.is_leaf(v), T.first_child(v), T.last_child(v), T.previous_sibling(v), T.next_sib
ling(v), T.is_first_child(v), and T.is_last_child(v) require scanning the whole array
and thus take O(n) time. The remaining operations can be implemented to take O(1)
time as follows:

• T.number_of_nodes() is the size of array P.


• T.is_root(v) is true if P[v] = nil, and false otherwise.
• T.parent(v) is equal to P[v].

First-Child, Next-Sibling

The first-child, next-sibling representation, on the other hand, consists of two arrays
of nodes, each of them with an entry for each node in the tree, where the entries
corresponding to node v have, respectively, the value first[v], or nil if v is a leaf node,
and next[v], or nil if v is a last sibling.

Definition 1.31 Let T = (V, E) be a tree with n nodes. The first-child next-sibling
representation of T is a pair (F, N ) of arrays of n nodes, indexed by the nodes
of the tree, where F[v] = first[v] if v is not a leaf node, F[v] = nil otherwise,
N [v] = next[v] if v is not a last child node, and N [v] = nil otherwise, for all nodes
v ∈ V.

Example 1.32 The array-of-parents representation of the tree T = (V, E) of


Fig. 1.23 is shown in Fig. 1.29. The first child and the next sibling of node v are
given by F[v] and N [v], respectively, for all nodes v ∈ V .

As with the array-of-parents representation, the arrays of first children and next
siblings are not necessarily arranged in any particular order, as long as they are
arranged in the same order. Anyway, there is an order on the nodes fixed by the repre-
sentation. Given the first-child, next-sibling representation of a tree, node precedence
is given by the order of the nodes as array indices, and precedence between sibling
nodes is also given by the order of array indices.
36 1 Introduction

Let T = (V, E) be a tree with n nodes, and let (F, N ) be the first-child, next-
sibling representation of T . Operations T.root(), T.is_root(v), T.parent(v), and
T.children(v) require scanning both of arrays F and N , and T.previous_sibling(v)
and T.is_first_child(v) require scanning array N , and thus take O(n) time. Further,
T.number_of_children(v) and T.last_child(v) require following up to children[v]
next-sibling links, where the former also requires following a first-child link, and
take O(children[v]) time. The remaining operations can be implemented to take
O(1) time as follows:

• T.number_of_nodes() is the size of array F, or the size of array N .


• T.is_leaf(v) is true if F[v] = nil, and false otherwise.
• T.first_child(v) is given by F[v].
• T.next_sibling(v) is given by N [v].
• T.is_last_child(v) is true if N [v] = nil, and false otherwise.

Graph-Based Representation of Trees

Trees can also be represented using the small set of abstract operations on graphs,
which can be implemented using either the extended adjacency list representation
or the adjacency map representation. The following operations are defined in terms
of the graph representation, using the abstract operations on basic data structures
presented in Sect. 1.2, as follows:

• T.number_of_nodes() is given by T.vertices().size().


• T.root() requires following the path of parent nodes starting off with any node of
the tree and then storing the root of the tree in the attribute root.

Fig. 1.29 First-child, next-sibling representation of a tree. Vertical arrows denote first-child links,
and horizontal arrows denote next-sibling links
1.3 Representation of Trees and Graphs 37

function root(T )
if T.root = nil then
return T.root
if T is empty then
return nil
v ← T.vertices().front()
while T.incoming(v) is not empty do
v ← T.parent(v)
T.root ← v
return v

• T.is_root(v) is given by T.incoming(v).empty().


• T.number_of_children(v) is given by T.outgoing(v).size().
• T.parent(v) is given by T.incoming(v).front().source().
• T.children(v) is given by the list [T.target(e) : e ∈ T.outgoing(v)].
• T.is_leaf(v) is given by T.outgoing(v).empty().
• T.first_child(v) is given by T.outgoing(v).front().target().
• T.last_child(v) is given by T.outgoing(v).back().target().
• T.previous_sibling(v) requires accessing the previous edge in the list of edges
coming out of parent[v].
function previous_sibling(T, v)
if T.is_root(v) then
return nil
e ← T.incoming(v).front()
u ← T.source(e)
if T.outgoing(u).prev(e) = nil then
return nil
else
return T.outgoing(u).prev(e).target()

• T.next_sibling(v) requires accessing the next edge in the list of edges coming out
of parent[v].
function previous_sibling(T, v)
if T.is_root(v) then
return nil
e ← T.incoming(v).front()
u ← T.source(e)
if T.outgoing(u).next(e) = nil then
return nil
else
return T.outgoing(u).next(e).target()
Discovering Diverse Content Through
Random Scribd Documents
A cette réponse, Trifaldin mit un genou en terre, puis, au triste
son des tambours et du fifre, il quitta le jardin du même pas qu'il y
était entré, laissant toute la compagnie étonnée de sa haute taille et
de son air tout à la fois vénérable et modeste.
Vous le voyez, vaillant chevalier, dit le duc en se tournant vers
don Quichotte, les ténèbres de l'ignorance et de l'envie ne sauraient
obscurcir l'éclat de la valeur et de la vertu: depuis six jours à peine
vous êtes dans ce château, et déjà l'on vient vous y chercher des
pays les plus lointains, non pas en carrosse ni à cheval, mais à pied
et à jeun, tant les malheureux ont d'empressement à vous voir, tant
ils ont de confiance en la force de votre bras et en la grandeur de
votre courage, grâce à la réputation que vos exploits vous ont
acquise, grâce au bruit qui en est répandu par tout l'univers.
Je regrette fort, seigneur duc, répondit don Quichotte, que ce
bon ecclésiastique qui l'autre jour montrait tant d'aversion pour les
chevaliers errants, ne soit pas témoin de ce qui se passe: il verrait
par lui-même si ces chevaliers sont ou non nécessaires au monde; il
pourrait du moins se convaincre que dans leur détresse les
malheureux ne vont pas chercher du secours auprès des hommes de
robe, ni chez les sacristains de village, ni chez le gentilhomme qui
n'a jamais franchi les limites de sa paroisse; en pareil cas, la
véritable panacée à l'affliction, c'est l'épée du chevalier errant.
Qu'elle vienne donc, cette duègne, qu'elle demande ce qu'elle
voudra; le remède à son mal lui sera bientôt expédié par la force de
mon bras et par l'intrépidité du cœur qui le fait agir.
CHAPITRE XXXVII
SUITE DE LA FAMEUSE AVENTURE DE LA DUÈGNE DOLORIDE

Le duc et la duchesse étaient charmés de voir don Quichotte


donner si complétement dans leurs vues; lorsque Sancho se mit de
la partie. Je voudrais bien, dit-il, que cette bonne duègne ne vînt pas
jeter quelque bâton dans les roues de mon gouvernement! car, je
tiens d'un apothicaire de Tolède, qui parlait comme un chardonneret,
que partout où se fourrent les duègnes, tout va de mal en pis. Dieu
de Dieu! comme il les détestait! et par ma foi, puisque toutes les
duègnes sont fâcheuses et impertinentes, que faut-il attendre d'une
affligée comme l'est, dit-on, cette comtesse Trifaldi?
Silence, Sancho, reprit don Quichotte: puisque cette dame vient
de si loin me chercher, elle ne peut être de celles dont parlait ton
apothicaire; de plus, elle est comtesse, et quand les comtesses
servent en qualité de duègnes, c'est auprès des reines et des
impératrices: car dans leurs maisons, elles sont dames et maîtresses
et se font servir par d'autres duègnes.
Madame la duchesse a pour suivantes des duègnes qui seraient
comtesses, si le sort l'eût voulu, repartit la señora Rodriguez qui était
présente; mais là vont les lois où il plaît aux rois. Cependant, qu'on
ne dise pas de mal des duègnes, surtout de celles qui sont vieilles
filles: car bien que je ne compte pas parmi ces dernières, je sens
l'avantage qu'une duègne fille a sur une duègne veuve. A quiconque
voudra nous tondre, les ciseaux resteront dans la main.
Ce ne sera pas faute de trouver à tondre sur les duègnes,
toujours suivant mon apothicaire, repartit Sancho: mais ne remuons
pas le riz, dût-il prendre au fond du pot.
Les écuyers ont toujours été nos ennemis, répliqua la señora
Rodriguez; véritables piliers d'antichambre, ces fainéants, au lieu de
prier Dieu, emploient leur temps à médire de nous, vont fouillant
dans notre généalogie, et font de rudes accrocs à notre réputation.
Eh bien, moi, je déclare ici, qu'en dépit d'eux nous continuerons à
vivre dans les grandes maisons, quoiqu'on nous y laisse mourir de
faim et qu'on nous y donne à peine une chétive robe noire pour
couvrir nos chairs délicates. Oui, si j'en avais le talent et le loisir, je
voudrais prouver, non-seulement aux personnes ici présentes, mais
encore au monde entier qu'il n'est point de vertu qui ne se rencontre
chez une duègne.
Je suis de l'avis de ma chère Rodriguez, dit la duchesse; mais elle
voudra bien remettre à une autre fois à défendre sa cause et celle
des duègnes, à réfuter les propos de ce méchant apothicaire, et à
faire revenir le grand Sancho de sa mauvaise opinion.
Par ma foi, madame, repartit Sancho, depuis que le
gouvernement m'est monté à la tête, je ne me souviens plus d'avoir
été écuyer, et je me moque de toutes les duègnes du monde comme
d'un fétu.
Ici la conversation fut interrompue par les deux tambours et le
fifre annonçant l'approche de la Doloride. La duchesse demanda à
son époux si elle ne devait pas aller au-devant de cette dame,
puisque c'était une comtesse et une femme de qualité.
Comme comtesse, ce serait chose juste, dit Sancho; comme
duègne, je ne conseille pas à Vos Excellences de faire un pas.
Eh! de quoi te mêles-tu, Sancho, reprit don Quichotte.
De quoi je me mêle, seigneur? répondit Sancho: je me mêle de
ce dont je puis me mêler, étant un écuyer nourri à l'école de Votre
Grâce, vous le chevalier le plus courtois de toute la courtoiserie. En
ces choses-là, je vous ai entendu dire qu'on risque autant de perdre
pour un point de plus que pour un point de moins; et à bon
entendeur salut.
Sancho a raison, ajouta le duc, il nous faut voir un peu quelle
mine a cette comtesse; d'après cela, nous mesurerons la politesse
qui lui est due.
En ce moment rentrèrent dans le jardin les tambours et le fifre
jouant leur marche ordinaire, toujours sur un ton lugubre, et l'auteur
termine ici ce court chapitre pour commencer le suivant, où se
continue la même aventure, une des plus remarquables de toute
l'histoire.
CHAPITRE XXXVIII
OU LA DUÈGNE DOLORIDE RACONTE SON AVENTURE

A la suite des musiciens parurent d'abord douze duègnes rangées


sur deux files, toutes vêtues de larges robes de mousseline blanche,
avec des voiles d'une telle longueur, qu'on n'apercevait que le bas de
leur vêtement; après elles venait la comtesse Trifaldi, donnant la
main à Trifaldin, son écuyer: elle était vêtue d'une robe de frise noire
à longue queue, terminée par trois pointes à angles aigus, que
portaient trois pages habillés de deuil. Cette partie de son
ajustement fit penser à tout le monde que la noble dame tirait son
nom de cette invention nouvelle. En effet, Trifaldi, c'est comme qui
dirait la comtesse à trois queues. Ben-Engeli en tombe d'accord,
mais en faisant remarquer que son nom propre était la comtesse
Loupine, à cause de la grande quantité de loups qui peuplaient ses
terres, tandis que si, au lieu de loups, c'eût été des renards, on
l'aurait appelée la comtesse Renardine. Quoi qu'il en soit, la
comtesse et ses douze duègnes s'avançaient lentement, le visage
couvert de voiles noirs si épais qu'il eût été impossible de rien
distinguer au travers. Sitôt qu'elles se furent arrêtées pour former la
haie, le duc et don Quichotte se levèrent; alors, passant au milieu
des duègnes, la Doloride, sans quitter la main de son écuyer, se
dirigea vers le duc, qui, avec toute la compagnie, s'avança pour la
recevoir.
Passant au milieu des duègnes, la Doloride se dirigea
vers le duc (p. 461).

Que Vos Grandeurs veuillent bien ne pas faire tant de courtoisies


à leur humble serviteur, je me trompe, à leur humble servante, car
mon affliction est telle que je ne pourrai jamais y répondre, tant ma
disgrâce étrange, inouïe, m'a emporté l'esprit je ne sais où, et ce
doit être fort loin, puisque plus je le cherche, moins je le trouve.
Il faudrait que nous l'eussions perdu tout à fait, madame la
comtesse, répondit le duc, pour ne pas reconnaître votre mérite, et
l'on ne saurait vous rendre trop d'honneurs.
En parlant ainsi il la releva, et la fit asseoir auprès de la
duchesse, qui l'accueillit avec beaucoup d'empressement. Don
Quichotte regardait sans prononcer un seul mot, tandis que de son
côté Sancho mourait d'envie de voir le visage de la comtesse Trifaldi
ou de quelqu'une de ses duègnes; mais il lui fallut y renoncer
jusqu'à ce qu'elles voulussent bien se découvrir elles-mêmes.
Chacun gardait le silence: ce fut enfin la Doloride qui le rompit
pour s'exprimer en ces termes: J'ai la confiance, très-haut et
puissantissime seigneur, très-belle et excellentissime dame, et très-
sages et illustrissimes auditeurs, que ma peine grandissime trouvera
un accueil favorable dans la générosité de vos sentiments, car mon
infortune est telle qu'elle est capable de faire pleurer le marbre,
d'attendrir le diamant et d'amollir l'acier des cœurs les plus endurcis.
Mais avant de porter jusqu'à vos courtoises oreilles le récit de mes
tristes aventures, je voudrais savoir si l'illustrissime chevalier don
Quichotte de la Manche et son fameusissime écuyer Panza sont dans
votre noble et brillante compagnie.
Panza est ici en personnissime, répliqua Sancho, et monseigneur
don Quichotte aussi; vous pouvez donc, très-honnêtissime dame,
dire tout ce qu'il vous plaira à votre agréabilissime fantaisie, et vous
nous trouverez diligentissimes à servir votre dolentissime beauté.
Madame, ajouta don Quichotte en s'adressant à la Doloride, si
vous croyez trouver un remède à vos malheurs dans le bras de
quelque chevalier errant, voici le mien; si faible qu'il soit, je le mets
tout à votre service. Je suis don Quichotte de la Manche, dont la
profession et le devoir sont de protéger et de défendre les affligés. Il
n'est pas besoin de détours ni de paroles éloquentes pour s'assurer
de ma bienveillance, vous n'avez qu'à raconter simplement vos
disgrâces; ceux qui vous écoutent, s'ils ne peuvent remédier à vos
maux, sauront du moins y compatir.
A ces paroles, la Doloride fit mine de se jeter aux genoux de don
Quichotte, et elle s'y jeta réellement, cherchant à les embrasser: Je
me prosterne devant ces pieds, devant ces jambes s'écria-t-elle, ô
invincible chevalier! comme devant les bases et les colonnes de la
chevalerie errante; laissez-moi baiser ces pieds que je ne saurais
trop révérer, puisque leurs pas doivent atteindre au terme de mes
maux, que Votre Grâce est seule capable de guérir, ô valeureux
errant, dont les merveilleux exploits font pâlir les fabuleuses histoires
des Amadis, réduisent en fumée les hauts faits des Bélianis, et
anéantissent les actions imaginaires des Esplandians! Puis, se
tournant vers Sancho, et le prenant par la main: Et toi, ajouta-t-elle,
ô le plus loyal écuyer qui ait jamais servi chevalier errant, dans les
siècles passés, présents et à venir; écuyer dont la bonté est encore
plus grande et plus longue que la barbe de mon écuyer Trifaldin, tu
peux t'enorgueillir à juste titre; puisqu'en servant le grand don
Quichotte, tu sers toute la valeur errante concentrée dans un seul
chevalier. Je te conjure, nobilissime écuyer, je te conjure par la
fidélité exorbitante de tes services, d'être un intercesseur bénévole
auprès de ton maître, afin qu'il favorise une infélicissime comtesse,
et ta très-humilissime servante.
Madame la comtesse, répondit Sancho, que ma bonté soit aussi
grande que la barbe de votre écuyer, ce n'est pas là ce dont il s'agit.
Au surplus, sans toutes ces câlineries et ces supplications, je prierai
mon maître (qui m'aime bien, je le sais, et surtout en ce moment
qu'il a besoin de moi pour certaine affaire) de vous favoriser et de
vous aider en tout ce qu'il pourra. Ainsi donc, ne vous gênez pas,
contez-nous votre peine, et vous verrez ce que nous savons faire.
Le duc et la duchesse étaient ravis de voir leur dessein si bien
réussir, car la Doloride faisait merveilles. La comtesse s'assit à la
prière du duc, et après que tout le monde eut fait silence, elle
commença de la sorte:
Sur le fameux royaume de Candaya, situé entre la grande
Trapobane et la mer du Sud, deux lieues par delà le cap Comorin,
régnait la reine Magonce, veuve du roi Archipiel, son époux. De leur
mariage était issue l'infante Antonomasie, qu'ensemble ils avaient
procréée. L'héritière du royaume me fut confiée en naissant et
grandit sous ma tutelle, parce que j'étais la plus ancienne et la plus
noble duègne de sa mère. Après bien des soleils (c'est ainsi que l'on
compte les jours en notre pays) la petite Antonomasie se trouva
avoir quatorze ans et plus de beauté que la nature en a jamais
départi à celles qu'elle a le mieux favorisées; son esprit n'était pas
en retard, car elle montrait déjà un très-bon jugement; enfin elle
était aussi discrète que belle, ou pour mieux dire elle est encore la
plus belle personne du monde, si le destin jaloux et les Parques au
cœur de bronze n'ont point tranché le fil délié de sa délicate vie; et
ils ne l'auront pas osé sans doute, car le ciel ne saurait permettre
qu'on fasse à la terre ce tort insigne, de couper toutes vertes les
grappes de la plus belle vigne qui en aucun temps se soit vue dans
le contour de sa vaste étendue.
De cette beauté sans pareille, et dont ma langue inculte ne
saurait assez dignement célébrer les louanges, devinrent amoureux
un nombre infini de princes, tant nationaux qu'étrangers. Mais parmi
tous ces soupirants, un simple chevalier, porté sur les ailes rapides
de son ambition démesurée, confiant dans sa jeunesse, sa bonne
mine, et la vivacité de l'esprit le plus heureux, osa lever les yeux
jusqu'au neuvième ciel de cette miraculeuse beauté. Je dois dire à
Vos Grandeurs qu'il jouait de la guitare à ravir; que de plus il était
poëte et grand danseur, et si adroit à fabriquer des cages d'oiseaux,
qu'il aurait pu gagner sa vie rien qu'à ce métier, s'il y eût été forcé
par le besoin. Avec tous ces mérites, de quoi ne viendrait-on pas à
bout? à plus forte raison du cœur d'une jeune fille; et cependant
toutes ces qualités n'auraient pas suffi à faire capituler la forteresse
dont j'étais gouvernante, si l'effronté scélérat n'eût habilement
commencé par me faire capituler moi-même. A force de cajoleries et
de présents, il flatta mon cœur et s'empara de ma volonté; mais ce
qui acheva ma défaite, ce fut certain couplet que j'entendis chanter
une nuit sous mes fenêtres; le voici, si je m'en souviens bien:

De l'éclat des beaux yeux de la cruelle Aminte


Il sort des traits ardents qui consument mon cœur;
Et parmi tous mes maux elle a tant de rigueurs,
Que même il ne faut pas qu'il m'échappe une plainte.

La strophe me sembla d'or, et la voix de miel; aussi depuis lors,


chaque fois que j'ai réfléchi sur ma faute, j'ai conclu en moi-même
que Platon avait eu raison de vouloir bannir les poëtes de toute
république bien ordonnée, au moins les poëtes érotiques, parce
qu'ils font des vers, non pas comme ceux du marquis de Mantoue,
bons tout au plus à divertir les petits enfants et à faire pleurer les
femmes, mais des vers qui sont autant d'épines qui percent le cœur,
et qui, de même que la foudre fond une épée sans attaquer le
fourreau, consument et brûlent le corps sans endommager les
habits. Une autre fois il me chanta ceux-ci:

O Mort! viens promptement contenter mon envie;


Mais viens sans te faire sentir,
De peur que le plaisir que j'aurais à mourir
Ne me rendît encor la vie.

Il m'en débita encore beaucoup d'autres, qui transportent quand


on les chante et qui ravissent quand on les lit. Mais, qu'est-ce, bon
Dieu! quand ces séducteurs s'avisent de composer certains
morceaux de poésie fort à la mode dans le royaume de Candaya, et
qu'on appelle seguidillas? Aussi, je le répète, on devrait les reléguer
dans quelque île par delà les antipodes. Après tout, cependant, il ne
faut point s'en prendre à eux, mais aux ignorants qui les louent et
aux sots qui les croient. Si j'avais été sur mes gardes, comme doit le
faire toute bonne gouvernante, je n'aurais pas prêté l'oreille à leurs
cajoleries, ni pris au sérieux leurs dangereux propos; tels que ceux-
ci: je vis en mourant, je brûle dans la glace, j'espère sans espoir, je
pars et je reste, et tant d'autres du même genre, dont ils farcissent
leurs écrits, et qu'on trouve d'autant plus beaux, qu'on les comprend
moins. N'ont-ils pas le front de nous promettre le phénix, la toison
d'or, la couronne d'Ariadne, l'anneau de Gigès, les pommes du jardin
des Hespérides, des montagnes d'or et des monceaux de diamants!
et pourtant on s'y laisse prendre comme s'ils en montraient des
échantillons. Mais à quoi me laissé-je entraîner, et quelle folie me
pousse à parler des faiblesses d'autrui, quand j'ai tant à dire sur les
miennes? Hélas! infortunée, ce ne sont pas ces vers, ces discours
qui t'ont abusée, ni ces sérénades qui t'ont perdue; c'est ton
imprudente simplicité, c'est ta faiblesse, c'est ton peu de
prévoyance, qui ont ouvert les sentiers et aplani le chemin aux
séductions de don Clavijo. Tel est le nom du chevalier. Sous mon
patronage, il entra non pas une fois, mais cent fois, dans la chambre
d'Antonomasie, abusée plutôt par moi que par lui, et cela sous le
titre de légitime époux, car, autrement, toute pécheresse que je suis,
je n'aurais jamais consenti qu'il eût seulement baisé le pan de sa
robe; oh! non, non, le mariage sera toujours en première ligne
quand je me mêlerai de semblables affaires. Dans celle-ci, il n'y avait
qu'un inconvénient, la différence des conditions, don Clavijo n'étant
qu'un simple chevalier, et l'infante Antonomasie étant princesse, et
de plus, comme je vous l'ai dit, l'héritière d'un grand royaume. Par
mes soins, l'intrigue demeura longtemps ignorée, jusqu'à ce qu'enfin
certaine enflure au-dessous de l'estomac de la jeune fille me fit juger
que le secret ne tarderait guère à être divulgué. Dans cette
appréhension, tous trois nous tînmes conseil, et l'avis unanime fut,
avant que le pot aux roses vînt à se découvrir, que par-devant le
grand vicaire, don Clavijo demandât pour femme Antonomasie en
vertu d'une promesse qu'il avait d'elle, promesse que j'avais moi-
même formulée, mais formulée avec tant de force qu'elle aurait défié
celle de Samson; bref, le grand vicaire vit la cédule, reçut la
confession de l'infante qui avoua tout, après quoi il la mit sous la
garde d'un honnête alguazil.
Comment! s'écria Sancho! il y a à Candaya des alguazils, des
poëtes et des seguidillas? Par ma foi, le monde est partout
semblable, à ce que je vois. Mais que Votre Grâce se dépêche, dame
Trifaldi: il est tard, et je meurs d'envie de savoir la fin de cette
histoire, qui, sans reproche, est un peu longue.
Vous allez l'apprendre, répondit la comtesse.
CHAPITRE XXXIX
SUITE DE L'ÉTONNANTE ET MÉMORABLE HISTOIRE DE LA COMTESSE

TRIFALDI

Chaque mot de Sancho enchantait la duchesse et désolait don


Quichotte, qui lui ordonna de se taire. La Doloride poursuivit:
Enfin, après bien des questions, comme l'infante ne variait point
en ses réponses et persistait dans ses dires, le grand vicaire
prononça en faveur de don Clavijo, et lui adjugea Antonomasie pour
légitime épouse, ce dont la reine Magonce eut tant de déplaisir, que
trois jours après on l'enterra.
Elle était donc morte? dit Sancho.
Assurément, répondit Trifaldin; car en Candaya nous n'enterrons
personne qu'il ne soit bien convaincu d'être mort.
Seigneur écuyer, repartit Sancho, ce ne serait pas la première fois
qu'on aurait enterré des gens évanouis, les croyant morts; et par ma
foi, vous en conviendrez, on n'a jamais vu mourir si vite que votre
reine Magonce: il me semble que c'eût été assez de s'évanouir, car
enfin on remédie à bien des choses avec la vie, et la folie de cette
infante n'avait pas été si grande, qu'il fallût se laisser mourir. Si cette
demoiselle eût épousé un de ses pages, ou quelque autre
domestique de sa maison, comme cela est arrivé à tant d'autres, le
mal eût été sans remède; mais épouser un chevalier aussi noble et
distingué que vous le dites, en vérité, ce n'est pas là un bien grand
malheur, et c'est aussi, je pense, l'avis de monseigneur don
Quichotte, qui est là pour me démentir: les chevaliers, surtout s'ils
sont errants, sont du bois dont on fait les rois et les empereurs, de
même qu'avec des clercs on fait des évêques.

Paris, S. Raçon, et Cie, imp.


Furne, Jouvet et Cie, édit.
Malambrun les enchanta tous deux sur la
tombe de la reine (p. 466).

Tu as raison, Sancho, reprit don Quichotte; oui, et pour peu


qu'un chevalier errant ait de chance, il est toujours au moment de se
voir le plus grand seigneur du monde. Mais continuez, madame, s'il
vous plaît; il me semble que le plus désagréable de cette histoire
reste à raconter, car ce que nous avons entendu jusqu'ici ne mérite
pas qu'on s'en afflige si fort.
En effet, répondit la comtesse, c'est le plus pénible qui reste à
dire, et même si pénible, que l'absinthe et les fruits sauvages n'ont
ni autant d'aigreur ni autant d'amertume. Dès que la reine fut morte,
nous l'enterrâmes, mais à peine, hélas! quis talia fando temperet a
lacrymis[110], à peine lui eûmes-nous dit le dernier adieu, que nous
vîmes subitement paraître au-dessus de sa tombe le géant
Malambrun, cousin germain de la défunte, monté sur un cheval de
bois et lançant sur les assistants des regards farouches. Ce géant,
aussi versé dans l'art du nécromant qu'il est vindicatif et cruel, était
là pour tirer vengeance de la mort de feu sa cousine, et pour châtier
l'audace de don Clavijo et la légèreté d'Antonomasie. Il les enchanta
tous deux sur la tombe de la reine: Antonomasie devint une guenon
de bronze, don Clavijo un effroyable crocodile d'un métal inconnu; et
entre eux fut placée une colonne également de métal, portant un
écriteau en langue syriaque: «Ces téméraires amants ne reprendront
leur forme première que lorsque le valeureux Manchois se sera
rencontré avec moi en combat singulier; c'est à sa valeur
incomparable que les immuables destins réservent une aventure si
extraordinaire.» Puis, il tira d'un large fourreau un démesuré
cimeterre, et m'ayant saisie par les cheveux, il fit mine de vouloir me
couper la tête; j'étais si troublée que je n'osais ni ne pouvais crier,
tant la frayeur me rendait immobile. Néanmoins, me rassurant de
mon mieux, je lui dis d'une voix tremblante de telles choses, qu'il
suspendit l'exécution de ce châtiment rigoureux. Bref, il fit amener
devant lui toutes les duègnes du palais, celles qui sont ici présentes;
et après nous avoir reproché notre défaut de surveillance, tempêté
contre les duègnes, en les chargeant toutes de la faute dont j'étais
coupable, il déclara ne pas vouloir nous infliger la perte de la vie,
mais un long supplice qui fût pour nous comme une espèce de mort
civile. A l'instant où il achevait ces paroles, nous sentîmes les pores
de notre visage se dilater, avec une vive démangeaison, semblable à
celle que causeraient des pointes d'aiguilles; et en y portant les
mains, nous nous trouvâmes dans l'état que vous allez voir.
Sur ce, la Doloride et ses compagnes ôtèrent leurs voiles, et
découvrirent des visages chargés d'épaisses barbes, les unes noires,
les autres blanches, d'autres rousses, et d'autres grisonnantes. A
cette vue, le duc, la duchesse et don Quichotte parurent frappés de
stupeur, et Sancho fut épouvanté. Voilà, dit la Trifaldi en continuant,
voilà dans quel état nous a mis ce scélérat de Malambrun, couvrant
la blancheur et la beauté de nos visages de ces rudes soies; trop
heureuses si par le fil acéré de son épouvantable cimeterre il nous
eût fait voler la tête de dessus les épaules plutôt que de nous rendre
ainsi difformes et velues comme des chèvres! Car en fin de compte,
seigneurs (et ce que je vais ajouter, je voudrais le faire avec des
yeux convertis en torrents, mais les mers de pleurs que j'ai versés en
pensant à nos disgrâces sont taries, aussi parlerai-je sans répandre
de nouvelles larmes); car en fin de compte, je vous le demande, où
osera se présenter une duègne barbue? qu'en diront les mauvaises
langues? quel père ou quelle mère voudront la reconnaître? et
puisqu'une duègne qui a le teint frais et poli, qui se martyrise le
visage à force de fards et de pommades, a tant de peine à plaire,
que sera-ce de celles qui sont velues comme des ours? O duègnes,
mes compagnes, que nous sommes nées sous une funeste étoile, et
qu'elle fut néfaste l'heure où nos mères nous ont mises au monde!
En prononçant ces paroles, la Doloride fit semblant de tomber
évanouie.
CHAPITRE XL
SUITE DE CETTE AVENTURE, AVEC D'AUTRES CHOSES DE MÊME

IMPORTANCE

Ceux qui aiment les histoires comme celle-ci doivent savoir gré à
son premier auteur, cid Hamet Ben-Engeli, pour l'attention qu'il met
à en raconter les plus minutieux détails. En effet, il découvre les
secrètes pensées, éclaircit les doutes, résout les objections, et, en
un mot, donne satisfaction sur tous les points à la curiosité la plus
exigeante. O incomparable auteur! ô infortuné don Quichotte! ô sans
pareille Dulcinée! ô réjouissant Sancho Panza! vivez de longs siècles,
ensemble ou séparément, pour le plaisir et l'amusement des
générations présentes et à venir.
L'histoire dit donc qu'en voyant la Doloride évanouie, Sancho
s'écria: Foi d'homme de bien, et par l'âme de tous les Panza mes
ancêtres, jamais, je le jure, je n'ai vu, ni entendu, ni rêvé, et jamais
non plus mon maître ne m'a raconté pareille aventure. Que mille
satans t'entraînent jusqu'au fond des abîmes, si cela n'est déjà fait,
maudit enchanteur de Malambrun! Ne pouvais-tu imaginer quelque
autre manière de punir ces créatures, sans les rendre barbues
comme des chèvres? Eh! ne valait-il pas mieux leur fendre les
naseaux, dussent-elles nasiller un peu, que de les gratifier de ces
barbes-là? Je gagerais mon âne qu'elles n'ont pas seulement de quoi
payer un barbier.
C'est la vérité pure, seigneur, répondit une des duègnes; entre
toutes, nous ne possédons pas un maravédis, aussi sommes-nous
forcées, par économie, d'user d'emplâtres de poix: nous nous les
appliquons sur le visage, et en les tirant tout d'un coup, nos
mentons demeurent lisses comme la paume de la main. Il y a bien à
Candaya des femmes qui vont de maison en maison épiler les
dames, leur polir les sourcils, et préparer certains ingrédients servant
à la toilette féminine[111], mais nous autres, duègnes de madame,
nous n'avons jamais voulu les recevoir, parce que la plupart font le
métier d'entremetteuses. Vous voyez donc que si le seigneur don
Quichotte ne vient à notre secours, nous emporterons nos barbes au
tombeau.
Je me laisserais plutôt arracher la mienne poil à poil par les
Mores, que de manquer à vous soulager, repartit notre héros.
En cet endroit, la comtesse Trifaldi reprit ses esprits, et
s'adressant à don Quichotte: L'agréable son de vos promesses,
valeureux chevalier, a frappé mes oreilles et suffit pour me rappeler
à la vie; je vous supplie de nouveau, errant, glorieux et indomptable
seigneur, de convertir promptement vos paroles en œuvres efficaces.
Il ne tiendra pas à moi, répondit don Quichotte; dites ce qu'il faut
que je fasse, et vous me trouverez prêt à vous servir.
Votre Magnanimité, saura donc, invincible chevalier, repartit la
Doloride, que d'ici au royaume de Candaya, si l'on y va par terre, il y
a cinq mille lieues, peut-être une ou deux de plus ou de moins; mais
si l'on y va par les airs et en ligne droite, il n'y en a que trois mille
deux cent vingt-sept. Vous saurez encore que le géant Malambrun
m'a dit qu'aussitôt que ma bonne fortune m'aurait fait rencontrer le
chevalier notre libérateur, il lui enverrait une monture
incomparablement meilleure et moins mutine que toutes les mules
de louage, car c'est le même cheval de bois sur lequel Pierre de
Provence enleva la belle Maguelonne; animal paisible et qu'on
gouverne au moyen d'une cheville plantée dans le front, mais qui
parcourt l'espace avec tant de légèreté et de vitesse, qu'on le dirait
emporté par le diable en personne. Ce cheval, disent les anciennes
traditions, est un ouvrage du sage Merlin, qui le prêta à son ami,
Pierre de Provence, lequel fit sur cette monture de très-longs
voyages par les airs, laissant ébahis ceux qui d'en bas le regardaient
passer. Merlin ne le prêtait qu'aux gens qu'il aimait, ou qui lui
payaient un bon prix: aussi n'avons-nous pas ouï dire que depuis le
fameux Pierre de Provence jusqu'à présent, personne l'ait monté.
Malambrun, par la force de ses enchantements, est parvenu à s'en
emparer; il s'en sert dans tous ses voyages: aujourd'hui il est ici,
demain en France, et le jour suivant au Potose ou en Chine. Le plus
merveilleux, c'est que ce cheval ne boit pas, ne mange pas, ne dort
pas et n'use point de fers; et il marche si bien l'amble, que celui qui
est dessus peut porter à la main une tasse pleine d'eau sans en
renverser une seule goutte: voilà pourquoi la belle Maguelonne
aimait tant à s'y trouver en croupe.
Pour avoir une douce allure, s'écria Sancho, vive mon grison! à
cela près qu'il ne marche point dans l'air; mais sur la terre, ma foi, il
défierait tous les ambles du monde.
Chacun se mit à rire, et la Doloride continua: Eh bien, si
Malambrun veut mettre fin à nos disgrâces, ce cheval sera ici après
la tombée de la nuit; car il me l'a dit, l'indice certain que j'aurai
trouvé le chevalier qui doit nous délivrer consiste à voir arriver
promptement le cheval partout où il en sera besoin.
Combien tient-t-on sur ce cheval? demanda Sancho.
Deux, répondit Doloride, un sur la selle et un autre en croupe; et
d'ordinaire ces deux personnes sont le chevalier et l'écuyer lorsqu'il
n'y a point de dame enlevée.
Madame, continua Sancho, comment appelle-t-on ce cheval?
La Doloride répondit: Il ne s'appelle pas Pégase, comme le cheval
de Bellérophon, ni Bucéphale, comme le cheval du grand Alexandre,
ni Bride-d'Or, comme celui de Roland, ni Bayard, comme celui de
Renaud de Montauban, ni Frontin, comme celui de Roger, encore
moins Bootès, ou Pirithoüs, comme se nommaient, dit-on, les
chevaux du Soleil; ni même Orélie, comme le coursier que montait le
malheureux Rodrigue, le dernier roi des Goths, dans la bataille où il
perdit le trône et la vie.
Puisqu'on ne lui a donné aucun des noms de ces chevaux
fameux, je gagerais bien, dit Sancho, qu'on ne lui a pas donné non
plus le nom du cheval de mon maître, Rossinante, celui de tous qui
me semble le mieux approprié à la bête.
Assurément, dit la comtesse; néanmoins il a un nom convenable
et significatif, car il s'appelle Chevillard le Léger, parce qu'il est de
bois et qu'il a une cheville au front, mais surtout à cause de sa
légèreté merveilleuse. Ainsi, quant au nom, il peut le disputer même
au fameux Rossinante.
Le nom me revient assez, reprit Sancho. Mais avec quoi le
gouverne-t-on? est-ce avec une bride ou avec un licou?
Je vous ai déjà dit, répondit la Trifaldi, que c'est avec la cheville:
en la tournant à droite ou à gauche, le cavalier le fait marcher
comme il l'entend, tantôt au plus haut des airs et tantôt rasant la
terre jusqu'à l'effleurer, tantôt dans ce juste milieu que l'on doit
chercher en toutes choses.
Je serais curieux de le voir, repartit Sancho, non pas pour monter
dessus, car de penser que jamais je m'y mette en selle ou en
croupe, votre serviteur: il serait bon, ma foi, qu'un homme qui a
déjà bien de la peine à se tenir sur son âne, assis sur un bât douillet
comme du coton, allât monter en croupe sur un chevron sans
coussin ni tapis! Oh! que nenni; je n'ai pas envie de me faire
écorcher le derrière pour ôter la barbe aux gens: qui a de la barbe
de trop se rase. Pour mon compte, je n'entends pas accompagner
mon maître dans un pareil voyage; d'ailleurs, je ne dois pas être
nécessaire dans ce rasement de barbes, comme je le suis dans le
désenchantement de madame Dulcinée.
Pardon, vous êtes nécessaire, repartit la Trifaldi, et même
tellement nécessaire, qu'on ne peut rien sans vous.
A d'autres, à d'autres, s'écria Sancho: qu'est-ce que les écuyers
ont à voir avec les aventures de leurs maîtres? Ceux-ci auraient
toute la gloire, et nous toute la peine. Encore, si les faiseurs
d'histoires disaient: Un tel chevalier a achevé une grande aventure
avec l'aide d'un tel son écuyer, sans quoi il lui aurait été impossible
d'en venir à bout; à la bonne heure. Mais au lieu de cela, ils vous
écrivent tout sec: Don Paralipomenon des trois Étoiles a mis fin à
l'aventure des six vampires; sans plus faire mention de l'écuyer que
s'il n'eût point été au monde, quoiqu'il fût présent, qu'il suât à
grosses gouttes, et qu'il y eût attrapé de bons horions. Encore une
fois, mon maître peut partir tout seul si cela lui convient, et Dieu
l'assiste! Quant à moi, je ne lui porte point envie, je resterai en
compagnie de madame la duchesse; et quand il sera de retour, peut-
être trouvera-t-il l'affaire de madame Dulcinée en bon chemin, car, à
mes moments perdus, je prétends m'étriller d'importance.

Voilà, dit la Trifaldi, voilà dans quel état nous a mis ce


scélérat de Malambrun (p. 466).

Mon ami, dit la duchesse, il faut pourtant accompagner votre


maître si cela est nécessaire, nous vous en conjurons tous; pour de
vaines frayeurs, il serait fort mal de laisser le visage de ces dames
en l'état où il est.
A d'autres encore une fois, répliqua Sancho; passe encore, si
c'était pour de jeunes recluses, ou pour de petites filles de la
doctrine chrétienne, on pourrait risquer quelques fatigues; mais
hasarder de se casser bras ou jambes pour tondre des duègnes, au
diable qui en fera rien; qu'elles cherchent d'autres tondeurs; dans
tous les cas, ce ne sera pas Sancho Panza. Pardieu! j'aime mieux les
voir toutes barbues comme des boucs, depuis la plus grande jusqu'à
la plus petite, depuis la plus mijaurée jusqu'à la plus pimpante.
Vous en voulez bien aux duègnes, ami Sancho, dit la duchesse,
et vous les épargnez encore moins que ne faisait votre apothicaire
de Tolède! En vérité, vous avez tort: il y a telle duègne qui peut
servir de modèle à toutes les femmes, et quand ce ne serait que ma
bonne señora Rodriguez ici présente... Je n'en veux pas dire
davantage.
Votre Excellence peut dire ce qui lui plaira, répondit la duègne;
Dieu sait la vérité de tout, et bonnes ou méchantes, barbues ou non
barbues, nous sommes, comme toutes les autres femmes, filles de
nos mères; et puisque Dieu nous a mises au monde, il sait pourquoi.
Aussi je compte sur sa miséricorde, et non sur la charité d'autrui.
La señora Rodriguez a raison, dit don Quichotte. Quant à vous,
comtesse Trifaldi et compagnie, espérez du ciel la fin de vos
malheurs; et croyez que Sancho fera ce que je lui ordonnerai. Je
voudrais que Chevillard fût ici, et déjà me voir aux prises avec
Malambrun; je lui apprendrai à persécuter les duègnes et à défier
des chevalier errants. Dieu tolère les méchants, mais ce n'est jamais
que pour un temps limité.
Valeureux chevalier, s'écria la Doloride, puissent les étoiles du ciel
regarder avec des yeux bénins Votre Grandeur, et verser sur votre
cœur magnanime toute la force et toute la prospérité qu'elles
enserrent, afin que vous deveniez le bouclier et le rempart des
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.

More than just a book-buying platform, we strive to be a bridge


connecting you with timeless cultural and intellectual values. With an
elegant, user-friendly interface and a smart search system, you can
quickly find the books that best suit your interests. Additionally,
our special promotions and home delivery services help you save time
and fully enjoy the joy of reading.

Join us on a journey of knowledge exploration, passion nurturing, and


personal growth every day!

ebookbell.com

You might also like