Spring 2017
Homework 6: Tree Serialziation
Due Monday, March 27th
Serializing Trees
For your 6th homework assignment, you will write two functions:
- (10 points) serialize This method writes a general tree out ot disk, using the "Print End of Child Marker" method. Use a ')' for the end-of-child marker. (Each node of the tree stores a single character, you may assume that ')' does not appear in the tree)
- (15 points) deserialize This method reads a general tree in from an input file (that was written out using the serialize method defined above)
I have provided scaffolding and testing code:
All you need to do is download these two files, and fill in the methods serialize and unserialize function stubs. The main program creates several general trees, and then serializes and deserializes them, so all the testing code is taken care of.File Formats
PrintStream
The serialize method takes as input parameters the tree to serialize and a PrintStream object you cam use for output. The syntax of the PrintStream object is the same as System.out (in fact, System.out is a PrintStream). So, to print out a single chararcter using a PrintStream object:
void testPrintStream(PrintStream p) { char c = ')' p.print(c); }
PushBackReader
Occasionally, when you read something form an input file, you might decide that you want to put back something that you have previously read. For instance, let's say that you are reading in (deserializing) a tree, and you want to distinguish between
A)and
AB)
So you read the first 'A', and then read the next character to see if it is a ')'. In the frist example above, we read the 'A', and then read the ')', and we know we are done with the 'A' subtree. What above the second example? We read the 'A', and then read the 'B'. So, we know we are not at the "end of child" marker, but we may want to return the 'B' to the input file so that a subsequent recursive call can handle it. The PushbackReader object allows us to push a characer back into the input stread afer we have read it.
We will only be using two methods of the PushbackReader: read, which reads in a single characer (and returns an int), and unread, which takes as input a single characeter.
WAIT A MINUTE! If read is supposed to read in a
single character, why does it return an int?!?!?! Well, read needs to
be able to read in a single character, and return either the next
character
public static testRead(PushbackReader inputFile) throws IOException { char c = (char) inputFile.read(); }
So, if we want to read in a character, and then put it back, we can do so as follows:
public static testRead(PushbackReader inputFile) throws IOException { // Read in a single character: char c = (char) inputFile.read(); // Put the caracter back! inputFile.unread(c); // The next time we call read, we will get the character c that // we pushed back }
Hints
- The serialize function can be wrtten using either the "Double Recursion" or "for loop to go through children" method. Either works just fine, though double recursion mehod is very elegant, and very few lones of code
- The deserialize function should problably not be written
using double-recursion. My solution uses recursion to go down
through the children, and a while loop to go through the sibling
list:
- Read in the first character, build a tree node N storing this character
- Create an (initially empty) list of childern
- While the next characer is not a ')':
- Recuursively create the next tree
- Add this tree to the end of the list of children
- Add this created list of children as the left child of N
- In deserialize, you will be reading in / creating the children of the root from left to right, and need to add each new child you read in to the end of the child list of the root -- so you may want to maintian a temporary "tail" pointer in the loop that reads in children, so that you don't acidentially reverse the child list ...