Runtime of MergeSort CSC 172 SPRING 2004 LECTURE 8
General No office hours for TFP on 2/11 Read Chapter 7 Project 2 is due Feb 18 You should have “insert term” working by now. If you don’t – do it. If you are stuck, see me or grad TAs immediately. How many students took MTH 150 Review of Induction? Review of Big-Oh? Review of recurrence relations?
Runtime Analysis of recursive code We use T(n) to say “it takes ‘T(n)’ time for some method to run on input of size ‘n’” Sometimes, it’s simple T(n) = O(n^2) Usual analysis and proof techniques Sometimes, when recursion is involved we resort to a recurrence relation T(n) = O(f(n)) + T(g(n)) We need to solve the recurrence relation
Example public void prntlst(Node n1) { if (n1 != null) { System.out.println(n1.getData()); prntlst(n1.getNext()); }
T(n) = O(1) + T(n-1) Example public void prntlst(Node n1) { if (n1 != null) { System.out.println(n1.getData()); prntlst(n1.getNext()); } T(n) = O(1) + T(n-1)
Recurrence Relation BASIS: T(0) = O(1) INDUCTION: T(n) = O(1) + T(n-1)
Recurrence Relation BASIS: T(0) = O(1) INDUCTION: T(n) = O(1) + T(n-1) To solve, let’s replace the O(1) with constants
Recurrence Relation BASIS: T(0) = a INDUCTION: T(n) = b + T(n-1) To solve, let’s replace the O(1) with constants
Recurrence Relation Expansion T(n) = b + T(n-1) So, T(n-1) = ?
Recurrence Relation Expansion T(n) = b + T(n-1) So, T(n-1) = b + T(n-2) T(n) = b + b + T(n-2) T(n) = b + b + b + T(n-3) …. T(n) = n*b + T(0) T(n) = n*b + a
Recurrence Relation Expansion Undo the replacement T(n) = n*b + a T(n) = n*O(1) + O(1) T(n) = O(n) + O(1) T(n) = O(n)
What is the RR for split? //O(1) //O(1) //O(1) //O(1) //O(1) //O(1) public static Node split(Node head){ Node secondNode; if (head == null) return null; else if (head.getNext() == null) return null; else { secondNode = head.getNext(); head.setNext(secondNode.getNext()); secondNode.setNext(split(secondNode.getNext()); return secondNode; } //O(1) //O(1) //O(1) //O(1) //O(1) //O(1)
What is the RR for split? //O(1) //O(1) //O(1) //O(1) //O(1) //O(1) public static Node split(Node head){ Node secondNode; if (head == null) return null; else if (head.getNext() == null) return null; else { secondNode = head.getNext(); head.setNext(secondNode.getNext()); secondNode.setNext(split(secondNode.getNext()); return secondNode; } //O(1) //O(1) //O(1) //O(1) //O(1) //O(1) //O(1) + T(n-2)
What is the RR for Merge? //O(1) //O(1) //O(1) //O(1) //O(1) public static Node merge(Node list1, Node list2){ if (list1 == null) return list2; else if (list2 == null) return list1; else if (list1.getData.compareTo(list2.getData()) < 1) { list1.setNext(merge(list1.getNext(),list2); return list1; } else { list2.setNext(merge(list1,list2.getNext()); return list2; } //O(1) //O(1) //O(1) //O(1) //O(1)
What is the RR for Merge? //O(1) //O(1) //O(1) //O(1) //O(1) public static Node merge(Node list1, Node list2){ if (list1 == null) return list2; else if (list2 == null) return list1; else if (list1.getData.compareTo(list2.getData()) < 1) { list1.setNext(merge(list1.getNext(),list2); return list1; } else { list2.setNext(merge(list1,list2.getNext()); return list2; } //O(1) //O(1) //O(1) //O(1) //O(1)
What is the RR for MergeSort? public static Node mergeSort(Node list){ Node secondList; if (list == null) return null; else if (list.getNext() == null) return list; else { secondList = split(list); return merge(mergeSort(list),mergeSort(secondList)); } //O(1) //O(1) //O(1) //O(n)
What is the RR for MergeSort? public static Node mergeSort(Node list){ Node secondList; if (list == null) return null; else if (list.getNext() == null) return list; else { secondList = split(list); return merge(mergeSort(list),mergeSort(secondList)); } //O(1) //O(1) //O(1) //O(n) What is the length of list? secondList? length(list) == length(secondList) = n/2
What is the RR for MergeSort? public static Node mergeSort(Node list){ Node secondList; if (list == null) return null; else if (list.getNext() == null) return list; else { secondList = split(list); return merge(mergeSort(list),mergeSort(secondList)); } //O(1) //O(1) //O(1) //O(n) //O(n) What is the length of list? secondList? length(list) == length(secondList) = n/2 So, what is the cost of the call to merge?
What is the RR for MergeSort? public static Node mergeSort(Node list){ Node secondList; if (list == null) return null; else if (list.getNext() == null) return list; else { secondList = split(list); return merge(mergeSort(list),mergeSort(secondList)); } //O(1) //O(1) //O(1) //O(n) //O(n) If the cost of mergeSort is TmergeSort(n): What is the cost of mergeSort is TmergeSort(list)? TmergeSort(secondlist)?
What is the RR for MergeSort? public static Node mergeSort(Node list){ Node secondList; if (list == null) return null; else if (list.getNext() == null) return list; else { secondList = split(list); return merge(mergeSort(list),mergeSort(secondList) ); } //O(1) //O(1) //O(1) //O(n) //O(n) Tmergesort(n) = O(1)+O(n)+2Tmergesort(n/2)
What is the RR for MergeSort?
Recurrence Relation for MergeSort Basis n == 0 TmergeSort(0) = O(1) Induction TmergeSort(n) = O(n) + 2TmergeSort(n/2)
Replace O(1)s by concrete constants TmergeSort(1) = a TmergeSort(n) = bn + 2TmergeSort(n/2) TmergeSort(n)/n = b + TmergeSort(n/2)/(n/2) TmergeSort(n/2)/(n/2) = b + TmergeSort(n/4)/(n/4) TmergeSort(n/4)/(n/4) = b + TmergeSort(n/8)/(n/8) TmergeSort(n/8)/(n/8) = b + TmergeSort(n/16)/(n/16) … TmergeSort(2)/(2) = b + TmergeSort(1)/(1) How many calls?
How many calls? log2n calls TmergeSort(n)/n = blog2n + TmergeSort(1)/(1) TmergeSort(n) = nblog2n + na TmergeSort(n) = O(nlog2n)