Download Recursive Linked Lists

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Quadtree wikipedia , lookup

B-tree wikipedia , lookup

Red–black tree wikipedia , lookup

Lattice model (finance) wikipedia , lookup

Interval tree wikipedia , lookup

Binary tree wikipedia , lookup

Linked list wikipedia , lookup

Binary search tree wikipedia , lookup

Transcript
CSC 207 (Fall 2015)—Recursive Linked Lists
Recursive Linked Lists Lab
This week, we’ll be discussing hierarchical structures, i.e., trees. Trees have a beautiful inductive
definition, but to appreciate that definition and turn it into a data structure, we’ll need to embrace
recursion. Before jumping into all of that, however, we’ll review programming with recursion.
Part 1: Recursive Linked Lists
It turns out that the linked lists that we explored in the last two weeks also have a beautiful
inductive definition that is closely related to the definition of a tree. It is precisely the definition of
list that you learned in CSC 161 with Racket. A list is either:
• Nil, empty, or
• Cons of some element and the rest of the list.
Using this definition of a List in Java is not that different from the imperative version we
studied previously. We use the same setup for a List as before:
public class LinkedList<T> {
private class Node {
public T value;
public Node next;
public Node(T value, Node next) { this.value = value; this.next = next; }
public Node(T value) { this(value, null); }
}
private Node first;
}
However, rather than using while-loops, we use recursion to do all of the work. Recall that
with recursion, we are trying to decompose our problem into a smaller version of itself. Most
commonly, when we solve a problem with recursion, we end up with two cases:
• A base case describing what to do at the base of the recursion, e.g., an empty list, the integer
is zero.
• A recursive case describing what to do when we’re not at a base case and we must decompose
the problem appropriately. Usually the recursive case consists of two parts: (1) breaking
down the problem and solving those smaller sub-problems with recursive calls and (2) taking
the results from those recursive calls and computing a solution for the overall problem.
For example, consider recursively adding an element to the end of the list: We may solve the
problem as follows:
• When the list is empty, we produce a new list of size one that contains that element.
• When the list is non-empty, we recursively add to the remainder of the list.
1
CSC 207 (Fall 2015)—Recursive Linked Lists
In a project called Trees, in a file called LinkedList.java, use the definition of a LinkedList
class above and implement the following methods using recursion:
• add(v): adds an element onto the end of the list.
• size(): returns the size of the list.
• contains(v): returns true if the element v is in the list.
• toString(): returns a string representation of the list, e.g., [0, 1, 2, 3, 4, 5].
• (Optional: remove(v): removes the first occurrence of v from the list, returning true if it is
successful; false otherwise).
Part 2: Trees
As mentioned above, a tree has a beautiful recursive definition as well. A (binary) tree is either:
• Nil, empty, or
• A Leaf of some element and a left sub-tree and a right sub-tree.
Pictorially, a tree looks as follows:
v
<left subtree>
<right subtree>
How does a (recursively defined) linked list differ from a tree? Using your linked list definition
as a starting point, define a class called Tree that implements a binary tree data structure as defined
above. Try implementing the basic container operations—add, size, contains, and toString—over
your Tree data structure. What differs between the linked list and tree operations? Do you need
any additional information to complete these methods?
2