1 | (50 pts) | Implement and test: add(char c, int pos) , add(char c) ,
and get(int pos) , plus
(for testing purposes) EditTree() , EditTree(char) ,
slowHeight() , slowSize() ,
ranksMatchLeftSubtreeSize() ,
toRankString() , and toString() . The tree does not have to be height-balanced,
only to pass the unit tests. |
2 | (70 pts) | All of the above, but now the tree must be kept height-balanced.
Plus: EditTree(EditTree e) , fastHeight() , and for testing,
toDebugString() , totalRotationCount() , and balanceCodesAreCorrect() . |
3 | (160 pts) | Final submission of all code: all of the above, plus delete(int pos) ,
EditTree(String s) , and get(int pos, int length) .
Includes correctness, efficiency constraints (see below), and style. |
EditorTrees is the major course project, as described in the syllabus.
This assignment is intended to be done in in teams of two, to practice and leverage the benefits of pair programming. You and your partner should work synchronously and frequently switch the two roles of driver and navigator.
In this project you will write methods of a class that could be the "behind the scenes" data structure used by a text editor. Each piece of text will be represented as a height-balanced tree with rank and balance codes. Each node contains a single character. Note that an EditTree is not an AVL tree in the traditional sense, since the order of nodes reflects their position within the tree's text rather than an alphabetical ordering of the characters in the tree. To repeat, this is not a Binary Search Tree, it is a balanced-tree implementation of Lists. For example, the text "SLIPPERY" could be represented by the height-balanced tree at the right.
You will focus on data structures and algorithms. You will not write a user interface with this.
Implement a complex data structure and associated algorithms.
More than any other in this course, this project will require you to design your algorithm ahead of time.
Make effective use of your debugger.
Read algorithm descriptions and use them as a basis for your Java code.
Gain additional practice with team skills.
You must implement all of the methods whose stubs are in the provided EditTree code. Each method that creates or modifies a tree must leave all trees height-balanced. Most of the requirements (including big-oh bounds on worst-case runtime) are presented to you as comments in that code, because context should make them clearer. These methods must run in O(log N) time, where N is the size (number of nodes) in the largest tree involved in the operation.
These methods must run in O(N) time, where N is the size
(number of nodes) in the tree involved in the operation.
The method get(int pos, int length) must run in O(length) time, where length is the parameter given. Hint: The way to do this is to recurse/iterate only over the nodes of the tree (and perhaps their immediate children) that contain data returned by the method.
The following required method is for grading purposes only: int totalRotationCount(), which returns the total number of rotations done in this tree since the tree was first created. A single rotation adds 1 to this count, a double rotation adds two.
Be sure to commit your versions often as you go, and mark your Milestone 1 and Milestone 2 submissions clearly in your commit log, so that we will know which one to grade! |
Certain operations would be really easy to implement if you didn't care about efficiency.
In order to do certain operations efficiently, like add() and get(), you already know that you need extra data in your nodes, a balance code. Here is another data member that is needed to implement the List interface efficiently: rank. First, some background. To access a node by index, that each node needs some way of figuring out that index it is in the tree. It would be nice if each node stored its index, but there is one problem: if you do an add(), then the index of every node after the added node would have to be incremented, and this takes longer than O(log n) time. Instead, we'll have each node store its own rank. Rank is defined as the 0-based index of the node within its own subtree (the one rooted at that node). If you check this, you'll see that it also happens to be the size of the node's left subtree. Ranks can be used to compute indices as you move down the tree, and can be updated after an add or delete in O(log n) time. Your code will need to:
You should also consider whether or not you want to add yet more data beyond balance code and rank:
Another decision you'll need to make is how to traverse your tree. For instance, when adding a node, you'll need to walk down the tree to figure out where to insert it, and back up to figure out if it needs to be rotated. How will you do this traversal? It may depend on the method. Some options:
debughelp
.
In that package are two classes, developed by CSSE230 student Philip
Ross, that display the tree nicely in a window, complete with rank and
balance code. You may use them if you like. The package also contains a sample of the output from the program, and
a README with instructions about what extra fields and methods you'll
need to add if you choose to use it. Many students have found it worth their time to use!