Please send questions to
st10@humboldt.edu .
/* Cs132BinaryTree.java 1.1 */
/* based on/modified from Ch. 11, "Java Structures", by */
/* D. Bailey, 2nd edition */
/* modified/adapted by Sharon Tuttle */
/* last modified: 4-3-03 */
public class Cs132BinaryTree
{
/*------------------------------------
fields
-------------------------------------*/
// information we want to be associated with this binary tree node
private Object value;
// parent of this node in the binary tree
private Cs132BinaryTree parent;
// left child of this node in the binary tree
private Cs132BinaryTree left;
// right child of this node in the binary tree
private Cs132BinaryTree right;
// how empty trees are represented in this particular
// binary tree implementation
public static final Cs132BinaryTree EMPTY = new Cs132BinaryTree();
/*------------------------------------------------------------------
constructors
(note: Purpose: statements are given for unusual constructors...)
-------------------------------------------------------------------*/
/*--------------------------------------------------
Cs132BinaryTree()
Purpose: PRIVATE constructor used for generating
an empty tree (a special Cs132BinaryTree
instance is used for this);
How strange is it for a user to not be able
to create an empty Binary Tree? Hmm.
------------------------------------------------------*/
private Cs132BinaryTree()
{
this.value = null;
this.parent = null;
// oddly (but intentionally), left and right
// subtrees are set to reference EMPTY, or this,
// rather than null; this allows programs to use
// empty trees... (see pp. 272-273, "Java Structures")
this.left = this;
this.right = this;
}
/*---------------------------------------------------------
Cs132BinaryTree(Object value)
Purpose: create a Cs132BinaryTree that contains this value
val in the root, and has empty left and right subtrees
(note that this one ISN'T private... it is for
public use)
--------------------------------------------------------------*/
public Cs132BinaryTree(Object val)
{
this.value = val;
this.parent = null;
// again, left and right subtrees are indicated
// as empty with the special EMPTY tree
this.left = EMPTY;
this.right = EMPTY;
}
/*---------------------------------------------------------
Cs132BinaryTree(Object val, Cs132BinaryTree lft,
Cs132BinaryTree rt)
Purpose: create a Cs132BinaryTree that contains this value
val in the root, has lft as its left subtree, and
has rt as its right subtree
(note that this one ISN'T private... it is for
public use)
--------------------------------------------------------------*/
public Cs132BinaryTree(Object val, Cs132BinaryTree lft,
Cs132BinaryTree rt)
{
// POSSIBLY NEW SYNTAX: notice that this will call
// the 1-Object-argument constructor on behalf of
// this new instance being constructed!
this(val);
// ...and, thus constructed, I can now call the
// modifiers to reset to left and right subtrees
// to those desired, instead of EMPTY
this.setLeft(lft);
this.setRight(rt);
}
/*-------------------------------------------------------
accessors
(note: Purpose: statements are given for accessors
that are not completely straightforward)
-------------------------------------------------------*/
public Object getValue()
{
return this.value;
}
/*------------------------------------------------------
getParent()
Purpose: returns reference to parent node, OR returns null
if there IS no parent
(given this implementation, parent data field is
already set to null if there is no parent...)
----------------------------------------------------------*/
public Cs132BinaryTree getParent()
{
return this.parent;
}
/*------------------------------------------------------
getLeft()
Purpose: returns reference to left subtree, or returns null
if there is "no" left subtree (for this implementation,
there is "no" left subtree if it is the special EMPTY
instance
--------------------------------------------------------------*/
public Cs132BinaryTree getLeft()
{
if (this.left == EMPTY)
{
return null;
}
else
{
return this.left;
}
}
/*--------------------------------------------------------
getRight()
Purpose: returns reference to right subtree, or returns null
if there is "no" right subtree (for this implementation,
there is "no" right subtree if it is the special EMPTY
instance
-----------------------------------------------------------*/
public Cs132BinaryTree getRight()
{
if (this.right == EMPTY)
{
return null;
}
else
{
return this.right;
}
}
/*-------------------------------------------------------
modifiers
(note: Purpose: statements are given for modifiers
that are not completely straightforward)
-------------------------------------------------------*/
public void setValue(Object newVal)
{
this.value = newVal;
}
/*-------------------------------------------------
setParent()
Purpose: makes parent of this tree newParent; if newParent
happens to be EMPTY, then parent of this tree is set
to be null instead.
-------------------------------------------------------*/
public void setParent(Cs132BinaryTree newParent)
{
if (newParent == EMPTY)
{
this.parent = null;
}
else
{
this.parent = newParent;
}
}
/*-------------------------------------------------------
setLeft()
Purpose: set this tree's left subtree to be newLeft.
additional complication, here! If newLeft is not EMPTY,
then it will now have this tree as ITS parent...
--------------------------------------------------------*/
public void setLeft(Cs132BinaryTree newLeft)
{
// cannot make a left subtree of an empty tree...
if (this.isEmpty())
{
return; // yes, if a function has a return type
// of void, you can say this...
}
// what if this node currently HAS a non-empty left subtree?
// it needs to no longer think of THIS node as its
// parent...
if (this.left.getParent() == this)
{
left.setParent(null);
}
// finally make this the new left subtree!
this.left = newLeft;
// and --- the new left subtree now needs THIS node
// as ITS parent...
newLeft.setParent(this);
}
/*-------------------------------------------------
setRight()
Purpose: set this tree's right subtree to be newRight.
additional complication, here! If newRight is not EMPTY,
then it will now have this tree as ITS parent
-------------------------------------------------------*/
public void setRight(Cs132BinaryTree newRight)
{
// cannot make a right subtree of an empty tree...
if (this.isEmpty())
{
return; // yes, if a function has a return type
// of void, you can say this...
}
// what if this node currently HAS a non-empty right subtree?
// it needs to no longer think of THIS node as its
// parent...
if (this.right.getParent() == this)
{
right.setParent(null);
}
// finally make this the new right subtree!
this.right = newRight;
// and --- the new right subtree now needs THIS node
// as ITS parent...
newRight.setParent(this);
}
/*------------------------------------------
overridden methods
-------------------------------------------*/
public String toString()
{
/* hmm; I think I'll have this just print the
value in this tree's root. Wonder if that'll
then help me with different traversals..? */
return "Cs132BinaryTree[root value:" + this.value + "]";
}
/*----------------------------------------------------
other methods
------------------------------------------------------*/
/*-----------------------------------------------------
isEmpty()
Purpose: returns true if this is an empty binary tree?
(is this useless for public, since cannot HAVE a public
empty binary tree of this class? should it just be private,
for use by getLeft(), getRight(), etc.?)
--------------------------------------------------------*/
public boolean isEmpty()
{
return (this == EMPTY);
}
/*--------------------------------------------------------
valuesInOrder()
Purpose: performs an in-order traversal of this binary
tree, creating a String containing the String
depiction of the objects contained within the
tree as they would be visited in an inOrder
traversal
-----------------------------------------------------------*/
public String valuesInOrder()
{
String result;
// base case!
if (this == EMPTY)
{
return "";
}
// recursive case: tree is NOT empty
return this.left.valuesInOrder() +
this.getValue() + " " +
this.right.valuesInOrder();
}
/*--------------------------------------------------------
valuesPreOrder()
Purpose: performs a pre-order traversal of this binary
tree, creating a String containing the String
depiction of the objects contained within the
tree as they would be visited in an preOrder
traversal
-----------------------------------------------------------*/
public String valuesPreOrder()
{
String result;
// base case!
if (this == EMPTY)
{
return "";
}
// recursive case: tree is NOT empty
return this.getValue() + " " +
this.left.valuesPreOrder() +
this.right.valuesPreOrder();
}
/*--------------------------------------------------------
valuesPostOrder()
Purpose: performs a post-order traversal of this binary
tree, creating a String containing the String
depiction of the objects contained within the
tree as they would be visited in an postOrder
traversal
-----------------------------------------------------------*/
public String valuesPostOrder()
{
String result;
// base case!
if (this == EMPTY)
{
return "";
}
// recursive case: tree is NOT empty
return
this.left.valuesPostOrder() +
this.right.valuesPostOrder() +
this.getValue() + " ";
}
} // end of class Cs132BinaryTree