E
- public class BinaryTreeNode<E> extends Object implements TreeOps<E>
Some binary tree nodes are considered "added" and others are not. Those nodes created for key elements added to the tree are "added" nodes. Those that are not added are those nodes created to serve as junctions for the added nodes. Only added elements contribute to the size of a tree. When removing nodes, non-added nodes are removed automatically whenever they are no longer needed, which is when an added node has less than two added sub-nodes.
BinaryTreeNode objects have a read-only API, in the sense that they cannot be constructed directly. Instead they are created indirectly by tree operations or by cloning existing nodes.
The API does allow you to remove them from trees, or to clone them. They can also be used to traverse a tree.
Nodes have various properties: the key, parent node, lower sub-node, upper sub-node, "added" property, and size. The "added" property can change if the node changes status following tree operations. If removed from a tree the parent property can change, and the sub-nodes can change when sub-nodes are removed from the tree, or other nodes are inserted into the tree, changing sub-nodes. However, none of these can be explicitly changed directly, they can only be changed indirectly by tree operations. The key of a node never changes.
Modifier and Type | Class and Description |
---|---|
static interface |
BinaryTreeNode.CachingIterator<N extends BinaryTreeNode<E>,E,C> |
Modifier and Type | Method and Description |
---|---|
Iterator<? extends BinaryTreeNode<E>> |
allNodeIterator(boolean forward)
Iterates through all the nodes of the sub-tree with this node as the root, in forward or reverse tree order.
|
void |
clear()
Removes this node and all sub-nodes from the tree, after which isEmpty() will return true.
|
BinaryTreeNode<E> |
clone()
Clones the node.
|
BinaryTreeNode<E> |
cloneTree()
Clones the sub-tree starting with this node as root.
|
Iterator<? extends BinaryTreeNode<E>> |
containedFirstAllNodeIterator(boolean forwardSubNodeOrder)
Returns an iterator that does a post-order binary tree traversal.
|
Iterator<? extends BinaryTreeNode<E>> |
containedFirstIterator(boolean forwardSubNodeOrder)
Returns an iterator that does a post-order binary tree traversal of the added nodes.
|
<C> BinaryTreeNode.CachingIterator<? extends BinaryTreeNode<E>,E,C> |
containingFirstAllNodeIterator(boolean forwardSubNodeOrder)
Returns an iterator that does a pre-order binary tree traversal.
|
Iterator<? extends BinaryTreeNode<E>> |
containingFirstIterator(boolean forwardSubNodeOrder)
Returns an iterator that does a pre-order binary tree traversal of the added nodes.
|
Iterator<E> |
descendingIterator()
Returns an iterator that iterates through the elements of the subtrie with this node as the root.
|
boolean |
equals(Object o)
Returns whether the key values match those of the given node
|
BinaryTreeNode<E> |
firstAddedNode()
Returns the first (lowest valued) added node in the sub-tree originating from this node,
or null if there are no added entries in this tree or sub-tree
|
BinaryTreeNode<E> |
firstNode()
Returns the first (lowest valued) node in the sub-tree originating from this node.
|
E |
getKey()
Gets the key used for placing the node in the tree.
|
BinaryTreeNode<E> |
getLowerSubNode()
Gets the direct child node whose key is smallest in value
|
BinaryTreeNode<E> |
getParent()
Gets the node from which this node is a direct child node, or null if this is the root.
|
BinaryTreeNode<E> |
getUpperSubNode()
Gets the direct child node whose key is largest in value
|
int |
hashCode()
The hash code is the hash code of the key value
|
boolean |
isAdded()
Some binary tree nodes are considered "added" and others are not.
|
boolean |
isEmpty()
Returns where there are not any elements in the sub-tree with this node as the root.
|
boolean |
isLeaf()
Returns whether this node is in the tree (is a node for which
isAdded() is true)
and additional there are other elements in the sub-tree with this node as the root. |
boolean |
isRoot()
Returns whether this is the root of the backing tree.
|
Iterator<E> |
iterator()
Returns an iterator that iterates through the elements of the sub-tree with this node as the root.
|
BinaryTreeNode<E> |
lastAddedNode()
Returns the last (highest valued) added node in the sub-tree originating from this node,
or null if there are no added entries in this tree or sub-tree
|
BinaryTreeNode<E> |
lastNode()
Returns the last (highest valued) node in the sub-tree originating from this node.
|
BinaryTreeNode<E> |
nextAddedNode()
Returns the next node in the tree that is an added node, following the tree order,
or null if there is no such node.
|
BinaryTreeNode<E> |
nextNode()
Returns the node that follows this node following the tree order
|
Iterator<? extends BinaryTreeNode<E>> |
nodeIterator(boolean forward)
Iterates through the added nodes of the sub-tree with this node as the root, in forward or reverse tree order.
|
int |
nodeSize()
Returns the count of all nodes in the tree starting from this node and extending to all sub-nodes.
|
BinaryTreeNode<E> |
previousAddedNode()
Returns the previous node in the tree that is an added node, following the tree order in reverse,
or null if there is no such node.
|
BinaryTreeNode<E> |
previousNode()
Returns the node that precedes this node following the tree order.
|
void |
remove()
Removes this node from the list of added nodes,
and also removes from the tree if possible.
|
void |
setAdded()
Make this node an added node, which is equivalent to adding the corresponding address to the tree.
|
int |
size()
Returns the count of nodes added to the sub-tree starting from this node as root and moving downwards to sub-nodes.
|
String |
toString()
Returns a visual representation of this node including the key, with an open circle indicating this node is not an added node,
a closed circle indicating this node is an added node.
|
String |
toTreeString(boolean withNonAddedKeys,
boolean withSizes)
Returns a visual representation of the sub-tree with this node as root, with one node per line.
|
boolean |
treeEquals(BinaryTreeNode<?> other)
Returns whether the sub-tree represented by this node as the root node matches the given sub-tree
|
int |
treeHashCode()
The hash code is the sum of the hash codes of all the added elements in the sub-tree with this node as the root
|
allNodeSpliterator, descendingSpliterator, nodeSpliterator, spliterator
public E getKey()
public boolean isRoot()
public BinaryTreeNode<E> getParent()
public BinaryTreeNode<E> getUpperSubNode()
public BinaryTreeNode<E> getLowerSubNode()
public boolean isAdded()
public void setAdded()
You cannot set an added node to non-added, for that you should remove the node from the tree by calling remove()
.
A non-added node will only remain in the tree if it needs to in the tree.
public int size()
public int nodeSize()
size()
, this is not a constant-time operation and must visit all sub-nodes of this node.public void remove()
public void clear()
public boolean isEmpty()
public boolean isLeaf()
isAdded()
is true)
and additional there are other elements in the sub-tree with this node as the root.public BinaryTreeNode<E> firstNode()
public BinaryTreeNode<E> firstAddedNode()
public BinaryTreeNode<E> lastNode()
public BinaryTreeNode<E> lastAddedNode()
public BinaryTreeNode<E> nextNode()
public BinaryTreeNode<E> previousNode()
public BinaryTreeNode<E> nextAddedNode()
public BinaryTreeNode<E> previousAddedNode()
public Iterator<E> iterator()
public Iterator<E> descendingIterator()
descendingIterator
in interface TreeOps<E>
public Iterator<? extends BinaryTreeNode<E>> nodeIterator(boolean forward)
nodeIterator
in interface TreeOps<E>
forward
- if true, goes in ascending order, otherwise descendingpublic Iterator<? extends BinaryTreeNode<E>> allNodeIterator(boolean forward)
allNodeIterator
in interface TreeOps<E>
forward
- if true, goes in ascending order, otherwise descendingpublic Iterator<? extends BinaryTreeNode<E>> containingFirstIterator(boolean forwardSubNodeOrder)
TreeOps
This iterator supports the Iterator.remove()
operation.
See the docs for TreeOps
for more details on the ordering.
containingFirstIterator
in interface TreeOps<E>
forwardSubNodeOrder
- if true, a left sub-node will be visited before the right sub-node of the same parent node.public <C> BinaryTreeNode.CachingIterator<? extends BinaryTreeNode<E>,E,C> containingFirstAllNodeIterator(boolean forwardSubNodeOrder)
TreeOps
This iterator supports the Iterator.remove()
operation.
Once a given node is visited, the iterator allows you to cache an object corresponding to the lower or upper sub-node that can be retrieved when you later visit that sub-node. That allows you to provide iteration context from a parent to its sub-nodes when iterating. The caching and retrieval is done in constant-time and linear space (proportional to tree size).
Here is an example showing usage of the caching. Consider this recursive code doing a pre-order traversal:
IPv6AddressTrie ipv6Tree = ...;
visitRecursive(ipv6Tree.getRoot(), null);
static <E> void visitRecursive(BinaryTreeNode<E> node, String direction) {
if(direction == null) {
direction = "root";
}
System.out.println("visited " + direction + " " + node);
BinaryTreeNode<E> sub = node.getLowerSubNode();
if(sub != null) {
visitRecursive(sub, direction + " left");
}
sub = node.getUpperSubNode();
if(sub != null) {
visitRecursive(sub, direction + " right");
}
}
The following iterative code provides the same functionality:
visitIterative(ipv6Tree.getRoot());
static <E> void visitIterative(BinaryTreeNode<E> node) {
CachingIterator<? extends BinaryTreeNode<E>, E, String>iterator = node.containingFirstAllNodeIterator(true);
while(iterator.hasNext()) {
BinaryTreeNode<E> next = iterator.next();
String direction = iterator.getCached();
if(direction == null) {
direction = "root";
}
System.out.println("visited " + direction + " " + next);
iterator.cacheWithLowerSubNode(direction + " left");
iterator.cacheWithUpperSubNode(direction + " right");
}
}
See TreeOps
for more details on the ordering.
containingFirstAllNodeIterator
in interface TreeOps<E>
forwardSubNodeOrder
- if true, a left sub-node will be visited before the right sub-node of the same parent node.public Iterator<? extends BinaryTreeNode<E>> containedFirstIterator(boolean forwardSubNodeOrder)
TreeOps
This iterator supports the Iterator.remove()
operation.
See TreeOps
for more details on the ordering.
containedFirstIterator
in interface TreeOps<E>
forwardSubNodeOrder
- if true, a left sub-node will be visited before the right sub-node of the same parent node.public Iterator<? extends BinaryTreeNode<E>> containedFirstAllNodeIterator(boolean forwardSubNodeOrder)
TreeOps
This iterator does not support the Iterator.remove()
operation.
If Iterator.remove()
is called it will throw UnsupportedOperationException
.
See TreeOps
for more details on the ordering.
containedFirstAllNodeIterator
in interface TreeOps<E>
forwardSubNodeOrder
- if true, a left sub-node will be visited before the right sub-node of the same parent node.public String toTreeString(boolean withNonAddedKeys, boolean withSizes)
withNonAddedKeys
- whether to show nodes that are not added nodeswithSizes
- whether to include the counts of added nodes in each sub-treepublic String toString()
public BinaryTreeNode<E> clone()
public BinaryTreeNode<E> cloneTree()
public int hashCode()
public int treeHashCode()
public boolean equals(Object o)
public boolean treeEquals(BinaryTreeNode<?> other)