TreeNode class and without a wrapper class.
TreeNodes will have many similarities to
ListNodes, there will be some differences:
parent() method, but unidirectional
links (parent to child) permit reuse of the same subtree in multiple
trees and may be easier to support.
setChild(). For example,
can you set the fifth child of a node with no children?
/** The value stored in the current node. */ protected Object value; /** The children of the current node. */ protected Node[] children;
pre: The new root value is non-null. pre: There is sufficient memory to create the new node.
/**
Construct a new node, given the root value and set of children.
post: A new node is constructed.
*/
public TreeNode(Object value, TreeNode[] children)
throws MemoryException
{
this.value = value;
// Create a new child array so that modifications to the original
// don't affect us.
this.children = new TreeNode[children.length];
if (this.children == null)
throw new MemoryException("Couldn't allocate children");
for (int i = 0; i < children.length; ++i) {
this.children[i] = children[i];
} // for
} // TreeNode(Object,Object[])
public TreeNode(Object value, Iterator children)
throws MemoryException
{
this.value = value;
// Determine the number of elements in the interator (hmmm ...
// should iterators have a size() method?)
int elements = 0;
for(children.reset();
children.hasMoreElements();
children.nextElement()) {
++elements;
} // for
// Allocate the new children array
this.children = new TreeNode[elements];
if (this.children == null)
throw new MemoryException("Couldn't allocate children);
// Copy
for(int i=0,children.reset();
(i < elements) && children.hasMoreElements(),
++i) {
this.children[i] = children.nextElement();
} // for
} // TreeNode(Object,Iterator)
/**
Create a new node with a particular value and arity.
pre: The arity is non-negative.
post: A new node is created.
*/
public TreeNode(Object value, int arity)
throws MemoryException
{
this.value = value;
this.children = new TreeNode[arity];
if (this.children == null)
throw new MemoryException("Can't allocate children");
} // TreeNode(Object,int)
/**
Create a new binary node with value and children.
post: A new node is created.
*/
public TreeNode(Object value, TreeNode left, TreeNode right)
throws MemoryException
{
this.value = value;
this.children = new TreeNode[2];
if (this.children == null)
throw new MemoryException("Can't allocate children");
this.children[0] = left;
this.children[1] = right;
} // TreeNode
/**
Get the value associated with the current node.
post: The value is returned.
*/
public Object getValue() {
return this.value;
} //getValue
/**
Get one of the children of the current node.
pre: The child number is non-negative.
pre: The child number is less than the arity of the current node.
post: The child or null is returned.
*/
public Object getChild(int childnum) {
// Sanity check removed
return children[childnum];
} // getChild
/**
Set the value associated with the current node.
pre: The value is non-null.
post: The current node now contains the new value.
*/
public void setValue(Object value) {
this.value = value;
} // setValue
/**
Set one of the children of the current node.
pre: The child number is non-negative.
pre: The child number is less than the arity of the current node.
post: The child is set.
*/
public void setChild(int childnum, TreeNode child) {
// Sanity check removed
children[childnum] = child;
} // setChild
deleteChild(n) is not strictly necessary, as we can
simply call setChild(n,null). However, it may be useful
to provide a separate deleteChild(n) so that we can choose
other ways to represent empty nodes.
TreeNode class)
/**
Build an interator for the tree rooted at the current node.
post: The iterator contains all the nodes currently in the tree.
*/
public Iterator elements() {
// We wouldn't really use a Linear here, but it makes a good
// generic exmaple.
Linear temp = new Linear();
addElements(temp);
return temp.elements();
} // elements()
/**
Add all the elements at or below the current node to a linear
structure. Note that there are many ways to do this, and the
way in which you do it (as well as the linear structure used)
affects the order in which elements appear.
pre: The linear structure is initialized.
pre: The lienar structure has room for the elements.
pre: The node is used in a tree (in particular, there is no path
from this node back to this node based only on child edges).
post: All the elements are added to the linear structure, even
if they are already there.
*/
private void addElements(Linear stuff) {
stuff.add(value);
for (int i = 0; i < children.length; ++i) {
if (children[i] != null)
children[i].addElements(stuff);
} // for
} // addElements()
Disclaimer Often, these pages were created "on the fly" with little, if any, proofreading. Any or all of the information on the pages may be incorrect. Please contact me if you notice errors.
Source text last modified Wed Nov 19 09:11:28 1997.
This page generated on Wed Nov 19 09:15:15 1997 by SiteWeaver.
Contact our webmaster at rebelsky@math.grin.edu