BDE 4.14.0 Production release
|
Encapsulate root, first, and last nodes of a tree with a count.
This component defines a single class, RbTreeAnchor
, providing access to the addresses of the root, first, and sentinel nodes of a tree, as well as the count of the number of nodes. A sentinel node is a value-less node, owned by the RbTreeAnchor
for the tree, that is used as the end-point for iteration over the nodes in a tree. RbTreeAnchor
provides modifiers for the firstNode
, rootNode
, and numNodes
properties, however the sentinel node for a tree is located at a fixed address and cannot be modified. An RbTreeAnchor
is similar to an in-core unconstrained attribute class, except that it does not supply equality-comparison, copy-construction, and copy-assignment operations.
The sentinel node is an RbTreeNode
object that does not have a value, and provides a fixed end-point for navigation over the tree. However, a sentinel node's attributes have different interpretations than those of other RbTreeNode
objects. Specifically, a sentinel node's leftChild
refers to the root of the tree, and its rightChild
refers to the first node of the tree. The following diagram shows the composition of a tree with RbTreeAnchor
and RbTreeNode
:
Notice that, counter-intuitively, the sentinel's right-child refers to the left-most (first) node of the tree. Also notice that RbTreeAnchor
doesn't hold a direct reference to the last (i.e., the right-most) node of the tree.
This section illustrates intended usage of this component.
This example demonstrates creating a simple tree of integer values using RbTreeAnchor
. Note that, in practice, clients should use associated utilities to manage such a tree (see bslalg_rbtreeutil ).
First, we define a node-type, IntTreeNode
, that inherits from RbTreeNode
:
Then, we define main
for our example, and create three nodes that we'll use to construct a tree:
Next, we create an RbTreeAnchor
, myTree
, which will hold the addresses of the root node and the first node of our tree along with a count of nodes, and then verify the attribute values of the default constructed object:
Then, we describe the structure of the tree we wish to construct.
Next, we set the properties for the nodes A
, B
, and C
to form a valid tree whose structure matches that description:
Now, we assign the address of A
and B
as the root node and the first node of myTree
respectively and set the number of nodes to 3:
Finally, we verify the attributes of myTree
:
This example demonstrates creating a function that inserts elements into a binary search tree. Note that, for simplicity, this function does not create a balanced red-black tree (see bslalg_rbtreeutil ).
First, we define a comparison functor for IntTreeNode
objects used by the insertion function:
Then, we declare the signature of a function insertNode
, which takes three arguments: (1) the anchor of the tree in which to insert the node (2) the new node to insert into the tree, and (3) a comparator, which is used to compare the payload values of the tree nodes. Note that the parameterized comparator is needed because a node's value is not accessible through the supplied RbTreeNode
.
Next, we find the location where newNode
can be inserted into searchTree
without violating the ordering imposed by comparator
, and then updates searchTree
with a potentially updated root node and first node.
If the root node of searchTree
is 0, we use the reset
function set the root node and the first node of searchTree
to newNode
and set the number of nodes to 1:
Then, we insert newNode
into the appropriate position by setting it as a child of parent
:
Next, we complete the insert function by incrementing the number of nodes in the tree:
Now, we create 5 IntTreeNode
objects and insert them into a tree using the insertNode
function.
Finally, we verify that the RbTreeAnchor
refers to the correct TreeNode
with its firstNode
and rootNode
attributes.