+ All Categories
Home > Documents > CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use...

CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use...

Date post: 30-Mar-2015
Category:
Upload: dennis-carvin
View: 218 times
Download: 2 times
Share this document with a friend
Popular Tags:
24
CO522 2009/10 1 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a list (for example, to print nodes or search for particular values). We could alternatively use recursion. often neater than iteration a useful introduction to recursion on linked structures has hidden costs that you need to understand to use it safely.
Transcript
Page 1: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 1

Recursion on linked lists

All the linked list examples we have seen so far use iteration when they need to work through the nodes of a list (for example, to print nodes or search for particular values).

We could alternatively use recursion.

often neater than iteration

a useful introduction to recursion on linked structures

has hidden costs that you need to understand to use it safely.

Page 2: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 2

Why use recursion

For more complex linked data structures, recursive methods are generally better than iterative ones

easier to understand

easier to write

efficient

Recursion on linked lists is useful learning exercise.

Page 3: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 3

Example – recursively printing nodes

Our Linked list class had a print() method that printed out the names and numbers from each of the nodes of the list in order.

We could do this recursively instead.

// Print out the entries in the list, one per line. public void print() { for (Node n = first; n != null; n = n.next) System.out.println(n.name + " " + n.number); }

Page 4: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 4

// Print out the entries in the list, // one per line. public void printr() { printr(first); } // Recursively print out the list starting at // start_node private void printr(Node start_node) { if (start_node == null) return; System.out.println(start_node.name + " " + start_node.number); printr(start_node.next); }

Page 5: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 5

Perspectives on recursion

Sanity check

How does it work?

How can I create a recursive solution to my problem?

What is going on behind the scenes?

What are the costs?

Page 6: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 6

Recursion Sanity Check

The recursive call should always be on a smaller data structure than the current one.

There must always be a non-recursive option if the data-structure is too small.

You often need a wrapper method to make the recursive method accessible.

in this case, the no-parameter printr() method

Page 7: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 7

How to understand how a recursive method works

Start off by working through what happens when it is called with a null list (no recursion happens).

Work through what happens when the list has only one node.

Look at 2 nodes

...

Page 8: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 8

How to write a recursive methodSuppose that you have an operation that you want to perform on a linked list:

1. Decide what to do if the list is empty.

2. Imagine that you are looking at the first node of a list and have already written the method so that you can use it on the remaining list.

3. Think how to put together a working algorithm for the whole list from your knowledge of the first node and the results of calling the (still unwritten) method for the rest of the list.

Page 9: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 9

Example: print out list nodes in reverse order

If the list is empty then the answer is to do nothing.

Now imagine that you have written the method and can use it on the remainder of the list after the first node.

To print out all the nodes in reverse order you call the the method to print the remaining nodes in reverse order then print out the first node.

Page 10: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 10

Reverse printing code

// Recursively print out the list in reverse // order. private void printr_rev(Node start_node) { if (start_node == null) return; printr_rev(start_node.next); System.out.println(start_node.name + " " + start_node.number); }

Page 11: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 11

It seems too good to be true

How could you do it without recursion?

reverse the order of the list, print out the nodes then reverse it again.

use an auxiliary data structure (a stack, say) to store the values as you iterate forward through the list. Then use the stored data to print out the values once you have reached the end of the list.

Both these are fiddly to program yet the recursive print method does it just by reversing the order of two lines of code.

Page 12: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 12

Stack Frames

Local Java method variables and parameters are created each time the method is called and destroyed when the method returns.

This is done on a stack, and the space used by an active method is called its stack frame

In addition to your local variables and parameters the stack frames can contain information used by debuggers and to generate diagnostics if the program crashes.

Page 13: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 13

Example

class MyClass {public static void main(String[] args) {

MyClass mc = new MyClass();foo(42);bar();

}

void foo(int n) {bar();

}

void bar() {int j = 7;

}}

Page 14: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 14

Method call walk-through

Active Methods Method stack

main's stack frameargs...

main

Page 15: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 15

Method call walk-through

Active Methods Method stack

main's stack frameargs...

mainfoo

foo's stack framen [42]

Page 16: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 16

Method call walk-through

Active Methods Method stack

main's stack frameargs...

mainfoobar foo's stack frame

n [42]

bar's stack framej [7]

Page 17: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 17

Method call walk-through

Active Methods Method stack

main's stack frameargs...

mainfoo

foo's stack framen [42]

Page 18: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 18

Method call walk-through

Active Methods Method stack

main's stack frameargs...

main

Page 19: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 19

Method call walk-through

Active Methods Method stack

main's stack frameargs...

mainbar

bar's stack framej [7]

Page 20: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 20

Method call walk-through

Active Methods Method stack

main's stack frameargs...

main

Page 21: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 21

Recursive method calls

Recursive methods are the same as none-recursive – each active method has its own stack frame.

Each recursive printr() method will have its own stack frame containing (at least) the start_node parameter it was called with.

After printr() has been called on the last node of a 1000 node list there will be 1000 printr() stack frames on the method stack.

Page 22: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 22

Print-orderBoth the forward and the reverse print methods generate a stack-frame for each node in the list. and also call println for each node in the list.

The difference is that the printr() method does its output as it is creating the stack. Then when it gets to the null at the end each of the printr() methods returns without doing anything else.

The printr_rev() does not produce any output as it is building the stack but does does it as the methods are returning and the stack is being dismantled.

Page 23: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 23

Stack Overflow

Java VM method-stack space is limited and a program will crash if the space runs out.

also true for other procedural languages like C

It is not a good idea to use recursion if the recursive method calls can go thousands deep.

e.g. printing out a long linked list.

Page 24: CO522 2009/1075 Recursion on linked lists All the linked list examples we have seen so far use iteration when they need to work through the nodes of a.

CO522 2009/10 24

Sorting a linked list

It is possible to use quicksort on a linked list but it is rather clumsy, and finding the middle node for the pivot is expensive.

Fortunately, there is another sorting algorithm, mergesort, that works well on linked lists but does not work on arrays.

Mergesort, like quicksort, is an n*logn algorithm but unlike quicksort it does not have any bad worst-case performance.


Recommended