Algorithms On Trees And Graphs With Python Code 2nd Edition Gabriel Valiente download
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
https://ebookbell.com/product/algorithms-on-trees-and-graphs-1st-
edition-prof-dr-gabriel-valiente-auth-4199916
https://ebookbell.com/product/algorithms-on-trees-and-graphs-
valiente-g-4580170
https://ebookbell.com/product/algorithms-on-strings-1st-maxime-
crochemore-christophe-hancart-1494028
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
https://ebookbell.com/product/optimization-algorithms-on-matrix-
manifolds-illustrated-edition-pa-absil-1075844
https://ebookbell.com/product/average-case-analysis-of-algorithms-on-
sequences-1st-edition-wojciech-szpankowski-4645760
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
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.
vii
Preface to the First Edition
ix
x Preface to the First Edition
References
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
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
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.
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 ).
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.
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
1 2 1 2 1 2
3 4 5 3 4 5 3 4 5
6 7 6 7 6 7
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.
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.
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.
1 2
3 4 5
6 7
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.
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.
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.
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].
connected if there are walks from v to w and from w back to v, for all vertices v and
w in the graph.
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.
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
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.
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.
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.
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
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.
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
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 )}.
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.
Complete graphs and cycle graphs are trivial examples of regular graphs. In a
regular graph, all vertices have the same degree.
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
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
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.
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.
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.
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.
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.
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.
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 ].
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.
Arrays
Matrices
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.
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.
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.
Priority Queues
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.
Dictionaries
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
• 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
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,
and in the following procedure, all those vertices of graph G which are adjacent with
vertex v are assigned in turn to variable w.
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.
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
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
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.
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]
function adjacent(v, w)
for all vertices x adjacent with vertex v in G do
if x = w then
return true
return false
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
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
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:
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:
Representation of Trees
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.
The following procedure is still another, more compact form of iteration over the
children w of a node v in a tree T .
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.
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:
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.
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:
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:
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.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
TRIFALDI
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.
ebookbell.com