CS3134 Homework #3
Due on October 28, 2004 at 11:00am

There are two parts to this homework: a written component worth 13 points, and a programming assignment worth 12 points. See the homework submission instructions on how to hand it in and for important notes on programming style and structure.

Written questions

  1. Expression parsing.
    1. (1 point) Convert the following infix expression to postfix based on the algorithm discussed in class and in the textbook.  Make sure to use PEMDAS conventions where appropriate: (4+7)/8+2*5-9*(4-5)
    2. (2 points) During postfix arithmetic evaluation, based on the result in (a), what's the deepest the stack gets (i.e., what's the maximum number of elements encountered during the processing of the postfix string) and at what point does it happen?  (If it happens at multiple points, identify the first point in the postfix string.)
  2. Doubly-linked, doubly-ended lists are fairly versatile data structures, but there's one major problem with them: scanning through them is still a tedious process -- for example, if you want to get to the middle of a linked list, it takes N/2 steps, even if you know what the value of N is. Compare this to an array, where going to the middle always takes one step. Let's see if we can come up with a better way.

    Imagine a doubly-linked list not only with "next" and "back" reference, but with a "nextnext" reference that points to the element after the next element. This enables us to skip through the list a bit quicker if we're scanning for a particular position, or if we have an ordered list and know approximately where our contents are.
    1. (2 points) Assuming we have a list with such a "nextnext" pointer, how many steps (i.e., absolute, not big-Oh) do we save for accessing the 50th element in a 100-element list over a traditional doubly-linked list?
    2. (1 point) Does the time saved above realize into a change in the big-Oh complexity for this access process as compared to a traditional doubly-linked list? Why or why not?
    3. (2 points) If we want to insert a new item in the middle of this list, what references do we have to modify? You can just list each of the references, the new value for each, and a brief explanation, or you can draw a diagram that shows this clearly, or you can give psuedocode for each and explain why the psuedocode works.
    4. (2 points) List the boundary conditions in this modified list (i.e., with respect to the references to be modified) and explain briefly how we'd address them (you don't need to write out the references or psuedocode for this).
    5. (3 points) Write out a jumpTo method that would belong in the new list class that takes one parameter: the index of the element we're looking for, and returns the Link element corresponding to that index (e.g., 5 would return the 6th item). Make sure you try and make this jumpTo as efficient as you can given this variation on the doubly-linked list. (Your code doesn't have to compile, but the syntax should be reasonably close to Java.  You can use the book's DoublyLinkedList code as a model; assume there's also a nextnext reference).
    (Trivia: this is the basis for a special data structure called a skip list, which is a cross between a tree and a linked list. It's a pretty cool data structure; do a Google search if you're curious about it.)

Programming problem

In this exercise, we're going to add some functionality to the DoublyLinkedList class that was provided in the book (page 226; you can download a copy here). There are three subparts to this assignment.

  1. (5 points) Implement a method that splits the doubly-linked list into two separate lists. To do this, build a method called split that takes a long as a parameter and returns a new object of type DoublyLinkedList. The method should search for the first instance of the supplied long, and split the list (or, to be more precise, reassign references) such that the found element should be the first element of the new DoublyLinkedList, and the element before it should be the last element of the old DoublyLinkedList. If that element doesn't exist, the method should return null. Make sure to take boundary conditions into account. Your algorithm should do the search in O(N) time and the actual splitting in O(1) time (e.g., you should not be actually copying the data itself around).
  2. (5 points) Implement a recursive count method, called recSize, that takes no parameters and returns an integer containing the total number of elements in the doubly-linked list.  To do this, have this method call another (private) method called recSize that takes two parameters: a reference to the first Link to be counted recursively, and a reference to the last Link to be counted recursively, and which returns an integer containing the total number of elements between those two Link objects. (Note that having two methods with the same name is legitimate Java syntax; it differentiates them by the parameter names. This is an OO concept known as overloading.)
  3. (2 points) The source file has a class called DoublyLinkedApp which is a tester for the DoublyLinkedList class.  Modify this tester to test the functionality of #1 and #2.  You're welcome to hardcode any test elements, but show that each of these work (for example, create a DoublyLinkedList, fill it with elements, split it, and show the two halves are correct).  You may find the displayForward method in the DoublyLinkedList class to be of help in demonstrating this.
  4. (3 points extra credit) While the book shows how to maintain a sorted linked list, it doesn't have an algorithm that actually sorts a doubly-linked list by moving Link elements around.  Implement insertion sort for this doubly linked list. To do this, create a method in the DoublyLinkedList class called insertionSort that takes no parameters and returns no values. This method will then do the same thing insertion sort does for an array, but instead will work on the linked list and will move whole links around instead of just data values.  If you decide to implement this, make sure to modify the DoublyLinkedApp class to demonstrate that your insertion sort algorithm works.  Note: make sure to diagram out the situation on paper; it's a bit tricky!

You must implement programming #2 recursively, not iteratively, to get any credit. You can check to make sure your method is recursive by seeing that the recSize methods doesn't use any loop constructs at all.