Download COMP1406/1006 Tutorial 10

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

Red–black tree wikipedia , lookup

Quadtree wikipedia , lookup

Lattice model (finance) wikipedia , lookup

Interval tree wikipedia , lookup

Binary search tree wikipedia , lookup

B-tree wikipedia , lookup

Linked list wikipedia , lookup

Transcript
COMP1406 - Winter 2014 - Tutorial 10
1: Recursive Data Structures - Linked Lists
Linked lists are discussed in §8.9 and §9.2 of the course notes. A linked list is one way in
which we implement the list abstract data type. Recall that a list is a collection of data
that has a sequential (linear) order. That is, there is a first element, a second element, . . . ,
and a last element.
The LinkedList class from the notes is actually a doubly-linked list. The class only
directly “sees” (has an attribute for) two of the items in the list: the first item and the last
item.
public class LinkedList{
Node head;
Node tail;
private int size;
...
}
// first element in the list
// last element in the list
// number of elements in the list
Each element in the list is stored in a node (or item class from the notes) and each node
is linked (has a reference to) two other nodes. Since linked lists are sequential containers
(the data being stored has a linear order just like in an array), we say that each node is
linked to the previous node and also to the next node. For simplicity, we’ll assume that the
elements in the list will be stored as a String object.
public class Node{
String data;
Node
next;
Node
previous;
}
For example, a linked list with three nodes (with data "cat", "dog" and "eel", in that
order) can be visualize as follows:
1
è Download the LinkedList and Node classes from the tutorial webpage. Look at this class
and make sure you understand how the add(Node), toString(), and most importantly, the
toStringHelper(Node) methods work. The toStringHelper method is a recursive private
helper method to generate a string representation of nodes linked together.
To help you work with linked lists and help you test your code, use the toString()
method to help you keep track of the current state of the linked list (by printing out its
contents in the proper order).
Thinking about Linked Lists
è Consider the following snippet of code.
Node n1 = new Node("panthro");
Node n2 = new Node("lion-o");
Node n3 = new Node("jaga");
Node n4 = new Node("cheetara");
Node n5 = new Node("tygra");
Node n6 = new Node("wilykit");
n2.next = n4;
n3.next = n1;
n5.next = n3;
n5.next.next.next = n6;
n6.next = n2;
Draw a memory model of the state of the computer after this code is run. (You should
draw a picture like the one drawn on the previous page. Note that none of the previous
references are defined.
è What commands are needed to make the sequence of Node objects (from above) a
LinkedList object? Which nodes are the head and tail nodes?
Linked List Functionality
è Write a boolean method find(String) that returns true if the input string is in the
linked list and false if not. Your solution must use recursion. Just as toString() uses
the recursive toStringHelper(Node) as a helper method, you will want to write a helper
method, findHelper(String, Node), to perform the actual recursion.
For example,
outputs
list.toString() −−−−→ <A, B, C, D, E>
outputs
list.find("F") −−−−→ false
outputs
list.find("E") −−−−→ true
2
è Since the LinbkedList class uses a doubly-linbked list, we should be able to move through
the list both forwards and backwards. Write a method toStringReverse() that returns a
string (just as toString()), but with the elements in reverse order. Again, you must use recursion for this. You will want a recursive helper method toStringReverseHelper(Node).
For example,
outputs
list.toString() −−−−→ <A, B, C, D, E>
outputs
list.toStringReverse() −−−−→ <E, D, C, B, A>
è Write a method called addBack(Node) that adds a node to the back of the linked list.
This method should not be recursive and it should not use iteration. It should be very
similar to the add(Node) method provided.
For example,
outputs
list.toString() −−−−→ <A, B, C, D, E>
outputs
list.addBack("end") −−−−→ <A, B, C, D, E, end>
outputs
list.addBack("E") −−−−→ <A, B, C, D, E, end, E>
è Write a method called add(Node newNode, int position) that inserts a node into a
linked list at a specified position. The position zero is the front/start of the list. If a negative
position is entered, it should add the element at position zero. If the position exceeds the
size of the linked list it should simply add to the back/end of the list. You must use
recursion for this problem. Again, use a recursive helper method.
For example, suppose list is a LinkedList object with 3 elements currently in it.
outputs
list.toString() −−−−→ <A, B, C>
outputs
list.add( new Node("q"), 0) −−−−→ <q, A, B, C>
outputs
list.add( new Node("dog"), 2) −−−−→ <q, A, dog, B, C>
outputs
list.add( new Node("end"), 15) −−−−→ <q, A, B, C, end>
outputs
list.add( new Node("wind"), 4) −−−−→ <q, A, B, C, wind, end>
è Write a method called remove(int) that removes the node at the specified position and
returns the data (the String) that is in that node. Again, position zero is the front/start of
the list. If a negative position is entered, the first node should be removed from the list and
its string returned by the method. If the position exceeds the size of the linked list it should
simply remove the last element in the list and return its string. You must use recursion
for this problem. Again, use a recursive helper method.
3
For example, suppose list is a LinkedList object with 5 elements currently in it.
outputs
list.toString() −−−−→ <A, B, C, D, E>
outputs
list.remove(1) −−−−→ "B"
outputs
list.toString() −−−−→ <A, C, D, E>
outputs
list.remove(1) −−−−→ "C"
outputs
list.toString() −−−−→ <A, D, E>
outputs
list.remove(12) −−−−→ "E"
outputs
list.toString() −−−−→ <A, D>
Extra
Work on these problems for extra practice working with recursion and linked lists. Each of
your solutions should involve recursion.
è Write a static method stringToLinkedList(String), that takes a string, in the format
of the output of the toString() method, and returns a linked list object based on the string.
For example,
list = stringToLinkedList("<A, B, C, D, E>")
outputs
list.toString() −−−−→ <A, B, C, D, E>
è Write a boolean method doubles() that checks if any two consecutive nodes in the current
linked list store the same string (data). The method should return true if there are two such
nodes satisfy this and false otherwise.
For example,
list = stringToLinkedList("<A, B, C, D, E>")
outputs
list.doubles() −−−−→ false
list.add(new Node("B", 7))
outputs
list.toString() −−−−→ <A, B, C, D, E, B>
outputs
list.doubles() −−−−→ true
è Write a static method merge(LinkedList, LinkedList) that takes as input two sorted
linked list object. That is, the nodes in each input linked list has data (strings) that are in
alphabetical (sorted) order. The method will create a new linked list object that consists of
all the data in both input lists in sorted order.
4
For example,
listA = stringToLinkedList("<A, D, Q, R>")
listB = stringToLinkedList("<B, C, F, P, R, W, Y, Z>")
listMerged = merge(listA, listB)
outputs
listMerged.toString() −−−−→ <A, B, C, D, F, P, Q, R, R, W, Y, Z>
è Assume that all strings (data attributes) are single character strings.
Write a static
method isPalindrome(LinkedList) that returns true of the ordering of the characters in
the input list are a valid palindrome and false otherwise. Use recursion to solve this problem.
Recall that a sequence of characters is a palindrome if and only if the sequence read
forward is the same the sequence read backwards.
For example,
list = stringToLinkedList("<W, O, r, r, O, W>")
outputs
isPalindrome(list) −−−−→ true
list.add("A")
outputs
isPalindrome(list) −−−−→ false
è Write a function insert(LinkedList, int) that inserts the input list into the current
linked list at the position specified.
For example,
outer = stringToLinkedList("<a, b, c, d, e, f>")
inner = stringToLinkedList("<cat, dog, eel>")
outer.insert(inner, 2)
outputs
outer.toString() −−−−→ <a, b, cat, dog, eel, c, e, f>
outer.insert(inner, 3)
outputs
outer.toString() −−−−→ <a, b, cat, cat, dog, eel, dog, eel, c, e, f>
5
Extra Extra
For this problem we will consider a singly-linked list. This is just the linked list we have
been using already, except that each node has no previous attribute. For our purposes, we’ll
just let previous = null for each node. We’ll also let tail = null.
è Write a static method called hasCycle(LinkedList) that determines if the input list has
a cycle in it. For example, the following linked list has a loop.
If this linked list was named list, hasCycle(list) should return true.
If you tried to visit each node in this linked list (using recursion or iteration) you would
keep visiting the last two nodes indefinitely until your program had stack overflow error
(recursion) or it you terminated the program since it was taking too long (iterative approach).
Note that the toString() method will not work properly with a single linked list because it
uses tail.
Note: This is a common interview question. It is worthwhile learning how to solve this.
More Recursion
If you are looking for more practice with recursive data structures, try working out the
binary tree problems found here: Tutorial Questions (Java Files)
6