# 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.

## Presentation on theme: "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."— Presentation transcript:

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 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.

CO522 2009/1076 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.

CO522 2009/1077 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); }

CO522 2009/1078 // 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); }

CO522 2009/1079 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?

CO522 2009/1080 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

CO522 2009/1081 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...

CO522 2009/1082 How to write a recursive method Suppose 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.

CO522 2009/1083 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.

CO522 2009/1084 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); }

CO522 2009/1085 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.

CO522 2009/1086 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.

CO522 2009/1087 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; }

CO522 2009/1088 Method call walk-through Active Methods Method stack main's stack frame args... main

CO522 2009/1089 Method call walk-through Active Methods Method stack main's stack frame args... main foo foo's stack frame n [42]

CO522 2009/1090 Method call walk-through Active Methods Method stack main's stack frame args... main foo bar foo's stack frame n [42] bar's stack frame j [7]

CO522 2009/1091 Method call walk-through Active Methods Method stack main's stack frame args... main foo foo's stack frame n [42]

CO522 2009/1092 Method call walk-through Active Methods Method stack main's stack frame args... main

CO522 2009/1093 Method call walk-through Active Methods Method stack main's stack frame args... main bar bar's stack frame j [7]

CO522 2009/1094 Method call walk-through Active Methods Method stack main's stack frame args... main

CO522 2009/1095 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.

CO522 2009/1096 Print-order Both 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.

CO522 2009/1097 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.

CO522 2009/1098 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.

Download ppt "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."

Similar presentations