|
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.