In this lab we will learn about using Java classes that reference themselves. Specifically, we will make a binary Tree class. Read the Wikipedia Binary Tree article to get a complete description of binary trees. For our purposes, a binary tree will have three fields; a (possibly empty) left sub-tree, an integer value that represents the "payload" of the root node of the tree, and a (possibly empty) right sub-tree. Our binary tree will have the feature that if there is a left sub-tree, then every value in the left sub-tree will be less that the value of the root. If there is a right sub-tree, then every value in the right sub-tree will be greater than or equal to the value of the root.
Make a lab03 directory in your cs140 directory.
Create a class called Tree in package lab03. This class should have three fields, a field called left which is a reference to the left sub-tree, an integer field called value, and a field called right which is a reference to the right sub-tree.
You should have a creator for the Tree class which accepts a variable number of integer arguments, which I called values. The first thing the creator needs to do is to ensure that there is at least one value in the values parameter. If not, the creator should execute the following instruction:
throw new IllegalArgumentException("Tree creator must have at least one value argument.");
This instruction "throws" an exception. We will learn about how to "catch" an exception later, but for now, when you "throw" an exception, it causes your program to stop, and the Java infrastructure prints information about what the exception was, and where you were in your code when the exception happened.
The creator should set the value of this node to the first element of the values parameter. Then it should loop through all remaining values in the values parameter, and invoke the insert method on that each remaining value. Note that when the creator is called, the left and right fields have already been initialized to "null" (which you can think of as "zero" for reference fields). That makes the left sub-tree and right sub-tree empty when the creator starts, which is what we want.
Obviously, we also need to write a insert method for the tree class, which takes a single integer argument called newval (along with the implicit this argument that points at the current Tree object). The insert method needs to insert the newal value in the existing tree. If newval is less than the value of this node, then we need to check to see if there is already a left sub-tree. If there is, then we insert the newval value into the existing left sub-tree. If there is not, then we create a new Tree with newval as an argument to the creator, and make that our left sub-tree. If newval is greater than or equal to value, we do the same thing with the right sub-tree. That is, insert newval in the right sub-tree if there is a right sub-tree, or make newval a new Tree that is the right sub-tree if not.
Note that the insert method invokes the Tree creator with a single argument. This works because the Tree creator takes a variable number of arguments, and a single argument is perfectly valid. The creator will create "this" node with empty left and right sub-trees, but since there is only one value, it will never call insert.
Finally, write a toString method for the tree class. The toString method should return a concatenation of the following strings...
When you have finished writing this class, compile it and make sure it compiles.
Write a Tester class with a main method. Start off with the following test:
Tree xmp = new Tree(24, 16, 33, 3, 41, 72, 66, 33, 12, 19, 99, 7, 32); System.out.println("Sorted numbers: " + xmp);
If you compile and run this, you should see output like...
Sorted numbers: 3, 7, 12, 16, 19, 24, 32, 33, 33, 41, 66, 72, 99
If you get something different, figure out what you did wrong and fix it.
Finally, add code to your main method in the Tester class to convert the command line arguments into integers, and to put these integers into another tree. Then, print out the string representation of the tree to see the sorted command line arguments. You can use the Java library function Integer.parseInt(args[i]) which converts the ith element of the args array into an integer, and returns the integer value.
Once this is coded and compiled, invoke your Tester method with a command like java -cp . lab03.Tester 24 16 33 3, and see what gets produced. What happens when you don't specify extra command line arguments? What happens if you specify command line arguments that aren't integers?
See if you can create a method in the Tree class called print which writes out a semi-graphic representation of the tree itself. See if you can make the value of the root node print on the left, and the values of the sub-trees to the right. Also, the left sub-tree should be above the root, and the right sub-tree should be below the root. I coded a routine to do this, and here is what it printed for the xmp tree above:
3 7 12 16 19 24 32 33 33 41 66 72 99
Change directories to the parent of the lab03 directory that contains all of your source code. Then create a zip file with your source code, using the following command:
> zip -r lab03_<userid>.zip lab03
where <userid> is your bmail user id. This will create a file called lab02_<userid>.zip that contains all of your source files. Please double check and make sure you .java files are in the zipped submission file! Now, go to MyCourses using your web browser, open the CS-140-B1 course, click on "Content"; then "Lab assignments" and then "Lab 03 Submission" and upload your zip file.
This lab is worth 10 points. You will get the full 10 points if your code compiles without warnings, and produces the correct output. The following are reasons for deductions:
If you do the extra credit, you will get up to 4 extra points added to your grade, as long as your grade does not exceed 10 points.