1 - Recursion on linked lists Lecture 7 ADS2 Lecture 7
Some recursive algorithms for linked lists 2 Will be working with a singly linked list of integers. Lists will just contain a head node. /**Node of a singly linked list of integers*/ public class IntNode { private int element; private IntNode next; /**default constructor*/ public IntNode(){ this(0,null); } /** Creates a node with the given element * and next node */ public IntNode(int i, IntNode n){ element=i; next=n; } ADS2 Lecture 7
Linked lists contd. 3 /**Returns the element of this node */ public int getElement(){return element;} /**Returns the next node of this node. */ public IntNode getNext(){return next;} //Modifier methods /**Sets the element of this node */ public void setElement(int i){element=i; } /**Sets the next field of this node. */ public void setNext(IntNode n){next = n;} } ADS2 Lecture 7
Linked lists contd. 4 Suppose we have a linked list L of IntNodes. A recursive algorithm to write the list to a string would be : Algorithm ToString(L): Input:Intlist L with head h Output: string representation of L if L is empty then return else L list with head h.next return(h.element + + ToString(L)) To implement this in Java we need a constructor to create a linked list with head n, where n is a node (IntNode in this case). ADS2 Lecture 7 /**constructor to create a list with head node n*/ public IntList(IntNode n){ head=n; }
Recursion on linked lists continued 5 /** String representation of list, recursive */ public String toString(){ IntList myList; if (isEmpty()) return ""; else{myList=new IntList(head.getNext()); return (head.getElement()+" " + myList.toString()); } Note that the newly created list myList is a singly linked list by usual definition: A singly linked list can be defined as: Either empty or A head node H whose next node points to a singly linked list. Can we come up with a similar recursive definition for a doubly linked list? See board. Will come back to this. ADS2 Lecture 7
Recursion on singly linked lists continued 6 (8) WritePos: Scan a linked list and output positive elements (9) Delete0: Delete the first node containing 0 in a linked list (10) Delete: delete all nodes containing a specified value from a linked list Some more Algorithms: First one is straightforward, others less so! In fact, with linked lists recursion is easiest when not changing list, just reading it. ADS2 Lecture 7
7 Algorithm WritePos(L): Input:Intlist L with head h Output: positive elements of L if L is not empty then if head.element>0 then print head.element L list with head h.next WritePos(L) /**output positive elements of list*/ public void writePos(){ if (!isEmpty()){ if(head.getElement()>0) System.out.print(head.getElement()+" "); IntList myList=new IntList(head.getNext()); myList.writePos(); } Recursive WritePos Algorithm + Java code Exercise: write pseudocode for recursive algorithm GetSize to return size of an IntList ADS2 Lecture 7
Recursion on singly linked lists when list may be changed ADS2 Lecture 78 In previous examples, after recursion list doesnt change. E.g. WritePos null head Examine head node, then perform algorithm on list with head node N. Head.next is still node N after recursion. N
Recursion on singly linked lists when list may be changed cont. ADS2 Lecture 7 9 But for some examples, after recursion list does change. E.g. Delete0 (remove first node containing value 0) null head Examine head node, then, if node doesnt contain value 0, perform algorithm on list with head node head.next. head.next should be node Q after recursion. So: need to reset head.next to head of smaller list when recursion is done. NQ
ADS2 Lecture 710 Recursive Delete0 Algorithm Algorithm Delete0(L): Input:Intlist L with head h Output: head of L with first node containing 0 removed if L is not empty then if head.element==0 then remove head return new head else L list with head h.next head.next Delete0(L) return head else return null Only removing first 0, so dont continue if have removed node Head of L may have changed! Example: see board
ADS2 Lecture 711 Recursive Delete0 Java code /**delete the first node containing 0 from list * and return the head of the list */ public IntNode delete0(){ if(!isEmpty()){ if (head.getElement()==0) {head=head.getNext();return head;} else{ IntList myList=new IntList(head.getNext()); head.setNext(myList.delete0()); return head; } else return null; }
ADS2 Lecture 712 Recursive Delete Algorithm Algorithm Delete(L,v): Input:Intlist L with head h, integer v Output: head of L with all nodes containing v removed if L is not empty then if head.element==v then remove head return delete(L,v) else L list with head h.next head.next Delete(L,v) return head else return null L is now smaller, so still applying to shorter list Example: see board. Note not assuming list is ordered
ADS2 Lecture 713 Recursive Delete Java code /**delete all nodes containing the value v from * list and return the head of the list */ public IntNode delete(int v){ if(!isEmpty()){ if (head.getElement()==v){ head=head.getNext(); return delete(v);} else{ IntList myList=new IntList(head.getNext()); head.setNext(myList.delete(v)); return head; } else return null; }
Recursion on doubly linked lists - harder ADS2 Lecture 714 When performing recursion on singly linked list in such a way as to (potentially) change list (e.g. adding a node in order, deleting nodes with given value), after recursion call have to reattach current list to head of the list being returned. Because singly linked lists have nice simple recursive definition, this is all we need to do. For doubly linked lists we also need to reset the prev node of the returned head to point to head of current list!
ADS2 Lecture 715 Recursion on doubly linked lists cont. A singly linked list can be defined as: Either empty or A head node H whose next points to a singly linked list. A doubly linked list D can be (loosely!) defined as: Either (i)empty or (ii)A head node H whose next and prev point to null, or (iii)A head node H whose - next points to a doubly linked list D (with head node H) and - prev points to null plus a reallocation of H.prev to H.
ADS2 Lecture 716 Recursion on doubly linked lists cont. Suppose we have a doubly linked list DIntList of DIntNodes (defined similarly as for IntNodes but with next and prev) Need a constructor to create a new doubly linked with head node n. /**constructor to create a list with head node n*/ public DIntList(DIntNode n){ head=n; if (head!=null) head.setPrev(null); } If we didnt set n.prev to null, the new list wouldnt be a doubly linked list!
ADS2 Lecture 717 Algorithm Delete0(L): Input:DIntlist L with head h Output: head of L with first node containing 0 removed if L is not empty then if head.element==0 then remove head return new head else L list with head h.next temp Delete0(L) head.next temp if (temp!=null) then temp.prev=head return head else return null E.g. Recursive Delete0 Algorithm for doubly linked list Reset prev of head of L
Lab 2 ADS2 Lecture 718 Available from moodle. You have to: Implement a generic singly linked list – including some recursive methods Implement a program to run a game, FindFredo. Must use recursion in two methods: power (v simple, but must use binary recursion) and recursiveFindFredo (more complex, use liner recursion).