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
- Expression parsing.
- (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 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.)
- 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.
- (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?
- (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?
- (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.
- (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).
- (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.
-
(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).
-
(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.)
-
(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.
-
(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.