Algorithms on Trees and Graphs: With Python Code 2nd Edition Gabriel Valiente instant download
Algorithms on Trees and Graphs: With Python Code 2nd Edition Gabriel Valiente instant download
https://ebookmeta.com/product/algorithms-on-trees-and-graphs-
with-python-code-2nd-edition-gabriel-valiente/
https://ebookmeta.com/product/applied-cryptography-protocols-
algorithms-and-source-code-in-c-2nd-edition-bruce-schneier/
https://ebookmeta.com/product/practical-channel-aware-resource-
allocation-with-matlab-and-python-code-michael-ghorbanzadeh/
https://ebookmeta.com/product/dewey-for-artists-1st-edition-mary-
jane-jacob/
Oblivious A Contemporary M M Best Friends to Lovers Gay
Romance Novel 1st Edition Leslie Mcadam
https://ebookmeta.com/product/oblivious-a-contemporary-m-m-best-
friends-to-lovers-gay-romance-novel-1st-edition-leslie-mcadam/
https://ebookmeta.com/product/treatment-of-voice-disorders-
second-edition-robert-thayer-sataloff/
https://ebookmeta.com/product/potential-exports-and-nontariff-
barriers-to-trade-maldives-national-study-1st-edition-asian-
development-bank/
https://ebookmeta.com/product/death-notice-zhou-haohui/
https://ebookmeta.com/product/come-to-papa-a-man-of-the-month-
club-novella-a-small-town-age-gap-romance-1st-edition-matilda-
martel/
Valiant Indian Warriors Philosophies, Approaches, and
Victories First Edition C. B. Bhange
https://ebookmeta.com/product/valiant-indian-warriors-
philosophies-approaches-and-victories-first-edition-c-b-bhange/
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:
There was a burden on her heart—the burden of the secret she had
not dared to confess either to Mr. Kelso or to her great-
grandparents.
She feared that they would not receive her if she confessed that she
had been married in secret to a man who had deserted her so
strangely, and that she had borne a little child that was dead and
had been buried in a secret grave.
"If I told them they might say, like Jewel, that it was all a sham, that
the man had deceived me," she thought, with burning cheeks. "They
might drive me out into the cold, hard world, of which I am so
terribly afraid. No, no, I dare not speak!"
So she kept her sorrowful secret hidden in her own heart; and when
Lady Ivon sometimes caught that look of sad retrospection on the
fair face, she thought that she was thinking of a dead lover—not a
dead husband and child.
"I fear that she must have cared more than I suspected," the old
lady would say to herself, uneasily; and, could she have gazed upon
Azalia now, she would have felt more anxious than ever.
She said to herself that she must find out the truth as to this Laurie
Meredith. But how to accomplish it was the question that occurred to
her, since she dare not ask any questions.
No answer presented itself to her mind, and she could only hope
that she might meet this Laurie Meredith in society.
"But what if I should meet Jewel, too? Would she recognize me?
Would she tax me with my identity? If she did, I should not
acknowledge the truth."
CHAPTER XXX.
It was perhaps a week after that snowy day when Azalia Brooke sat,
looking back with dim, wet eyes into her shadowy past, that Jewel
Fielding reclined at ease in a beautiful boudoir hung in white and
gold, and listened to the roar of the winter wind as it whistled in the
eaves of the handsome but ancient old mansion that she called
home.
The house had been built by an Englishman almost a century ago,
and outside it looked like a small-sized castle, while within it was of
peculiar construction, having some very large and beautiful rooms,
with others so small and ill-ventilated that Jewel turned up her pretty
nose at them, declaring that they were stuffy holes, fit for nothing
that she could see but lumber-closets. There was a great, big,
noisome cellar under the house, too, that in winter often stood feet
deep in water, and was therefore never used for any purpose, but
given over to the use and occupancy of immense rats.
But there were plenty of elegant, comfortable rooms in the grand
house, and the beautiful boudoir where Jewel lay was fine enough
for a queen, and Jewel herself was not unlike a queen in her purple
velvet robe, with its border of silvery fur that was so becoming to
the dusky beauty of her dark, sparkling face, with its crown of jetty
braided hair.
It was a gloomy, overcast afternoon, with a keen, north-east wind
blowing, and heavy patches of last week's deep snow still cumbering
the ground. But the curtains were drawn and the gas ablaze in
Jewel's room, while the leaping flames inside the grate added
tropical warmth to the large room with its beautiful furniture and tall
stands of blooming flowers.
Jewel's eyes were shining with pleasure, for her maid had just
brought in for her inspection a new dress that she was to wear that
night—a marvel of richness, a stately purple brocade and plush, in
which, with her costly diamonds, Jewel knew that she would look
imperially lovely.
"Leave it there, Marie," she said to the pert French maid with her
dainty, beribboned cap; "I wish to study the fall of the drapery at my
leisure. I will ring when I desire you."
Marie bowed and withdrew, and the vain beauty lay idly at full
length, her arms thrown over her head, her dainty slipper tapping
the carpet, and feasted her dark eyes on the shining robe.
"I shall look like a queen—there will be no one to rival me!" she
declared, triumphantly. "Let me see, what flowers shall I wear?—
crimson roses, or creamy-white ones? Or the delicate gold of the
Maréchal Niel? I declare, I can not make up my mind. I shall have to
let Marie decide. She has exquisite taste."
Suddenly a slight frown wrinkled the beautiful forehead, and the
dark eyes flashed.
"Ah, I forgot," she muttered. "They say that that English beauty will
be there! Pshaw! What does it matter? I shall eclipse my Lord Ivon's
great-granddaughter, in spite of the prestige of her position, for they
say she is a blonde, and her pink-and-white charms will stand no
chance against my brunette beauty. All blondes look insipid. I never
saw but one that could hold her own against me, and that was my
twin sister—ah, I forgot—I mean Flower."
She shivered a little, and the slow opening of the door gave her a
violent start.
It was Marie, who had been flirting with the postman at the door.
She carried a letter on a salver.
Jewel snatched it up eagerly, and dismissed her maid.
In a moment she had drawn the letter from the envelope and was
quickly perusing it.
Her face darkened with anger, and she gnawed her crimson lower lip
sharply with her pearly teeth, muttering vindictively:
"I will not do it—never, never! She shall stay there till she dies!"
CHAPTER XXXI.
Again the door opened, and Jewel thrust the letter into the envelope
and slipped her hand down among the folds of her rich gown.
"Marie, what do you mean by interrupting me like this?" she broke
out, petulantly.
Marie courtesied, apologized, and explained that a lady, a woman,
had called to see Miss Fielding, and would not be denied.
"What do you mean by a lady, a woman?" Jewel mimicked,
impatiently; and the maid explained, in broken French, that the
caller had a high-bred voice and air, but was dressed very shabbily,
and had come on foot.
"Her name?" Jewel demanded.
But the shabby caller had given the maid no card.
"Why did you not send her to Mrs. Wellings since she would not go
away?"
Mrs. Wellings had gone to her room with a headache, and desired no
one to disturb her in the little nap with which she proposed to while
away the dull afternoon.
"Headache! too much wine at luncheon!" Jewel muttered, scornfully;
and then, having nothing else to do, and being of a curious
disposition, she said, lightly: "Go, and show your impertinent shabby
lady up here, Marie, and I will find out what she wishes. A beggar,
perhaps—insolent creature!"
Marie withdrew, and Jewel threw herself into an attitude of studied
grace, the better to impress the caller, whom she opined was some
poor creature, a needle-woman desiring work, most probably.
The door opened, and a slight, dark figure, very poorly dressed,
indeed, followed Marie over the threshold and stood there hesitating.
Jewel looked at her curiously, but a dark veil was drawn over the
features of the unknown.
"Well?" she interrogated, curtly and haughtily.
"Send your maid away, please, Miss Fielding," said a low, imploring
voice that made Jewel start in spite of her haughty self-command.
She immediately motioned Marie away, and, rising quickly, turned
the key in the lock after her exit.
Then, with a swift tremor shaking her whole frame, she confronted
the veiled figure.
"Now," she said, sharply, and the veil was flung aside by an agitated
hand, and Jewel and Flower, the long-parted half-sisters, the
beautiful rivals, stood face to face!