Lecture26 - Engineering 101 Lecture 26 Recursion and Merge...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: Engineering 101 Lecture 26 Recursion and Merge Sort Prof. Michael Falk University of Michigan, College of Engineering Announcements Project 6 (simulating cardiac tissue) is due Monday Nov 13, 9pm Exam 3 Monday Nov 20, 7-9pm Early Admin Friday Nov 17, 3-5pm Recursion A program that calls itself is called recursive. Example: int factorial (int n){ if (n==0) return 1; else return n* factorial(n-1); } Recursion factorial (4) return 4* factorial(3) Recursion factorial (4) return 4* factorial(3) factorial (3) return 3* factorial(2) Recursion factorial (4) return 4* factorial(3) factorial (3) return 3* factorial(2) factorial (2) return 2* factorial(1) Recursion factorial (4) return 4* factorial(3) factorial (3) return 3* factorial(2) factorial (2) return 2* factorial (2) factorial(1) return 1* factorial(0) Recursion factorial (4) return 4* factorial(3) factorial (3) return 3* factorial(2) factorial (2) return 2* factorial (2) factorial(1) return 1* 1 Recursion factorial (4) return 4* factorial(3) factorial (3) return 3* factorial(2) factorial (2) return 2* 1 Recursion factorial (4) return 4* factorial(3) factorial (3) return 3* factorial(2) factorial (2) return 2 Recursion factorial (4) return 4* factorial(3) factorial (3) return 3* 2 Recursion factorial (4) return 4* factorial(3) factorial (3) return 6 Recursion factorial (4) return 4* 6 Recursion 24 Exercise 1 What will be output if the string "up down" is passed to the procedure? 1- upay downay 2- puay ownday 3- upay 4- puay downay ownday Exercise 1 What will be output if the string "up down" is passed to the procedure? 1- upay downay 2- puay ownday 3- upay 4- puay downay ownday Exercise 2 void dothis (string text){ if (text.size()==0){ cout << endl; return; } int n = text.find(" "); if (n==text.npos){ n=text.size(); cout << text.substr(1,n-1) << text.substr(0,1); cout << "ay" << endl; return; } cout << text.substr(1,n-1) << text.substr(0,1); cout << "ay "; dothis (text.substr(n+1,text.size()-n-1)); return; } find() locates a number in a sorted list. What parameters should be passed in the last call to find()? 1- list, mid+1, end, num 2- list, begin, mid+1, num 3- list, mid-1, end, num 4- list, begin, mid-1, num Exercise 2 Exercise 2 find() locates a number in a sorted list. What parameters should be passed in the last call to find()? 1- list, mid+1, end, num 2- list, begin, mid+1, num 3- list, mid-1, end, num 4- list, begin, mid-1, num Example 3 int find (const vector <int> & list, int begin, int end, int num){ int mid = (begin + end)/2; if (list[mid] == num) return mid; if (list[mid] < num) return find(list, mid+1, end, num); if (list[mid] > num) return find(list, begin, mid-1, num); } Bubble Sort void bubblesort( vector<int> & list){ int i; // Up to which have we sorted? int j; // Which are we comparing? for(i=list.size( )-1; i > 0; i=i-1) for(j=0; j< i; j=j+1) if (list.at(j) > list.at(i)) swap(list.at(i), list.at(j)); return; } Recursive Bubble Sort void bubblesort( vector<int> & list, int i){ // i = Up to which have we sorted? int j; // Which are we comparing? if (i ==1) return; for(j=0; j < i-1; j=j+1) if (list.at(j) > list.at(i)) swap(list.at(i), list.at(j)); bubblesort(list, i-1) return; } How long does bubble sort take? The first number is compared to N-1 others The second is compared to N-2, etc. (N-1)+(N-2)+(N-3)+....+1 = N(N-1)/2 So we have to make 1/2N2-1/2N comparisons We say the algorithm is O(N2) Another Sort of Sort What if we write a procedure that will merge two sorted list into a combined sorted list? 1 2 What if we write a procedure that will 3 merge two sorted list into a combined 4 sorted list? 5 2 1 6 3 5 7 4 6 8 7 8 9 9 10 10 Another Sort of Sort template<class T> void merge( const T & a, const T & b, T & c){ c.resize(a.size() + b.size() ); int aindex=0, bindex=0; for( int i=0; i<c.size(); i=i+1) if(aindex==a.size()){ c[ i ] = b[bindex]; bindex = bindex + 1; }else if (bindex==b.size()){ c[ i ] = a[aindex]; aindex = aindex + 1; }else if (a[aindex] < b[bindex]){ c[ i ] = a[aindex]; aindex = aindex + 1; } else { c[ i ] = b[bindex]; bindex = bindex + 1; } } Merge a 2 3 4 7 9 b 1 5 6 8 10 template<class T> void merge( const T & a, const T & b, T & c){ c.resize(a.size() + b.size() ); int aindex=0, bindex=0; First create a new for( int i=0; i<c.size(); i=i+1) vector that is the if(aindex==a.size()){ size of the other c[ i ] = b[bindex]; two combined bindex = bindex + 1; }else if (bindex==b.size()){ c[ i ] = a[aindex]; aindex = aindex + 1; }else if (a[aindex] < b[bindex]){ c[ i ] = a[aindex]; aindex = aindex + 1; } else { c[ i ] = b[bindex]; bindex = bindex + 1; } } Merge c a 2 3 4 7 9 b 1 5 6 8 10 template<class T> void merge( const T & a, const T & b, T & c){ c.resize(a.size() + b.size() ); aindex and bindex int aindex=0, bindex=0; for( int i=0; i<c.size(); i=i+1) will track the if(aindex==a.size()){ progress through c[ i ] = b[bindex]; the two lists bindex = bindex + 1; a and b }else if (bindex==b.size()){ c[ i ] = a[aindex]; aindex = aindex + 1; }else if (a[aindex] < b[bindex]){ c[ i ] = a[aindex]; aindex = aindex + 1; } else { c[ i ] = b[bindex]; bindex = bindex + 1; } } Merge c a 2 3 4 7 9 b 1 5 6 8 10 template<class T> void merge( const T & a, const T & b, T & c){ c.resize(a.size() + b.size() ); loop over each int aindex=0, bindex=0; for( int i=0; i<c.size(); i=i+1) element in the if(aindex==a.size()){ combined list and c[ i ] = b[bindex]; figure out what the bindex = bindex + 1; element should be. }else if (bindex==b.size()){ c[ i ] = a[aindex]; aindex = aindex + 1; }else if (a[aindex] < b[bindex]){ c[ i ] = a[aindex]; aindex = aindex + 1; } else { c[ i ] = b[bindex]; bindex = bindex + 1; } } Merge c a 2 3 4 7 9 b 1 5 6 8 10 template<class T> void merge( const T & a, const T & b, T & c){ c.resize(a.size() + b.size() ); if we have int aindex=0, bindex=0; exhausted the a for( int i=0; i<c.size(); i=i+1) list then take the if(aindex==a.size()){ next from the b list c[ i ] = b[bindex]; and increment bindex = bindex + 1; bindex }else if (bindex==b.size()){ c[ i ] = a[aindex]; aindex = aindex + 1; }else if (a[aindex] < b[bindex]){ c[ i ] = a[aindex]; aindex = aindex + 1; } else { c[ i ] = b[bindex]; bindex = bindex + 1; } } Merge c a 2 3 4 7 9 b 1 5 6 8 10 template<class T> void merge( const T & a, const T & b, T & c){ c.resize(a.size() + b.size() ); if we have int aindex=0, bindex=0; exhausted the b for( int i=0; i<c.size(); i=i+1) list then take the if(aindex==a.size()){ next from the a list c[ i ] = b[bindex]; and increment bindex = bindex + 1; aindex }else if (bindex==b.size()){ c[ i ] = a[aindex]; aindex = aindex + 1; }else if (a[aindex] < b[bindex]){ c[ i ] = a[aindex]; aindex = aindex + 1; } else { c[ i ] = b[bindex]; bindex = bindex + 1; } } Merge c a 2 3 4 7 9 b 1 5 6 8 10 template<class T> void merge( const T & a, const T & b, T & c){ c.resize(a.size() + b.size() ); otherwise take int aindex=0, bindex=0; from the list with for( int i=0; i<c.size(); i=i+1) the lowest if(aindex==a.size()){ remaining value c[ i ] = b[bindex]; and increment bindex = bindex + 1; its index }else if (bindex==b.size()){ c[ i ] = a[aindex]; aindex = aindex + 1; }else if (a[aindex] < b[bindex]){ c[ i ] = a[aindex]; aindex = aindex + 1; } else { c[ i ] = b[bindex]; bindex = bindex + 1; } } Merge c 1 a 2 3 4 7 9 b 1 5 6 8 10 template<class T> void merge( const T & a, const T & b, T & c){ c.resize(a.size() + b.size() ); int aindex=0, bindex=0; for( int i=0; i<c.size(); i=i+1) if(aindex==a.size()){ c[ i ] = b[bindex]; bindex = bindex + 1; }else if (bindex==b.size()){ c[ i ] = a[aindex]; aindex = aindex + 1; }else if (a[aindex] < b[bindex]){ c[ i ] = a[aindex]; aindex = aindex + 1; } else { c[ i ] = b[bindex]; bindex = bindex + 1; } } Merge c 1 2 a 2 3 4 7 9 b 1 5 6 8 10 template<class T> void merge( const T & a, const T & b, T & c){ c.resize(a.size() + b.size() ); int aindex=0, bindex=0; for( int i=0; i<c.size(); i=i+1) if(aindex==a.size()){ c[ i ] = b[bindex]; bindex = bindex + 1; }else if (bindex==b.size()){ c[ i ] = a[aindex]; aindex = aindex + 1; }else if (a[aindex] < b[bindex]){ c[ i ] = a[aindex]; aindex = aindex + 1; } else { c[ i ] = b[bindex]; bindex = bindex + 1; } } Merge c 1 2 3 a 2 3 4 7 9 b 1 5 6 8 10 template<class T> void merge( const T & a, const T & b, T & c){ c.resize(a.size() + b.size() ); int aindex=0, bindex=0; for( int i=0; i<c.size(); i=i+1) if(aindex==a.size()){ c[ i ] = b[bindex]; bindex = bindex + 1; }else if (bindex==b.size()){ c[ i ] = a[aindex]; aindex = aindex + 1; }else if (a[aindex] < b[bindex]){ c[ i ] = a[aindex]; aindex = aindex + 1; } else { c[ i ] = b[bindex]; bindex = bindex + 1; } } Merge c 1 2 3 4 a 2 3 4 7 9 b 1 5 6 8 10 template<class T> void merge( const T & a, const T & b, T & c){ c.resize(a.size() + b.size() ); int aindex=0, bindex=0; for( int i=0; i<c.size(); i=i+1) if(aindex==a.size()){ c[ i ] = b[bindex]; bindex = bindex + 1; }else if (bindex==b.size()){ c[ i ] = a[aindex]; aindex = aindex + 1; }else if (a[aindex] < b[bindex]){ c[ i ] = a[aindex]; aindex = aindex + 1; } else { c[ i ] = b[bindex]; bindex = bindex + 1; } } Merge a 2 3 4 7 9 b 1 5 6 8 10 c 1 2 3 4 5 template<class T> void merge( const T & a, const T & b, T & c){ c.resize(a.size() + b.size() ); int aindex=0, bindex=0; for( int i=0; i<c.size(); i=i+1) if(aindex==a.size()){ c[ i ] = b[bindex]; bindex = bindex + 1; }else if (bindex==b.size()){ c[ i ] = a[aindex]; aindex = aindex + 1; }else if (a[aindex] < b[bindex]){ c[ i ] = a[aindex]; aindex = aindex + 1; } else { c[ i ] = b[bindex]; bindex = bindex + 1; } } Merge a 2 3 4 7 9 b 1 5 6 8 10 c 1 2 3 4 5 6 template<class T> void merge( const T & a, const T & b, T & c){ c.resize(a.size() + b.size() ); int aindex=0, bindex=0; for( int i=0; i<c.size(); i=i+1) if(aindex==a.size()){ c[ i ] = b[bindex]; bindex = bindex + 1; }else if (bindex==b.size()){ c[ i ] = a[aindex]; aindex = aindex + 1; }else if (a[aindex] < b[bindex]){ c[ i ] = a[aindex]; aindex = aindex + 1; } else { c[ i ] = b[bindex]; bindex = bindex + 1; } } Merge a 2 3 4 7 9 b 1 5 6 8 10 c 1 2 3 4 5 6 7 template<class T> void merge( const T & a, const T & b, T & c){ c.resize(a.size() + b.size() ); int aindex=0, bindex=0; for( int i=0; i<c.size(); i=i+1) if(aindex==a.size()){ c[ i ] = b[bindex]; bindex = bindex + 1; }else if (bindex==b.size()){ c[ i ] = a[aindex]; aindex = aindex + 1; }else if (a[aindex] < b[bindex]){ c[ i ] = a[aindex]; aindex = aindex + 1; } else { c[ i ] = b[bindex]; bindex = bindex + 1; } } Merge a 2 3 4 7 9 b 1 5 6 8 10 c 1 2 3 4 5 6 7 8 template<class T> void merge( const T & a, const T & b, T & c){ c.resize(a.size() + b.size() ); int aindex=0, bindex=0; for( int i=0; i<c.size(); i=i+1) if(aindex==a.size()){ c[ i ] = b[bindex]; bindex = bindex + 1; }else if (bindex==b.size()){ c[ i ] = a[aindex]; aindex = aindex + 1; }else if (a[aindex] < b[bindex]){ c[ i ] = a[aindex]; aindex = aindex + 1; } else { c[ i ] = b[bindex]; bindex = bindex + 1; } } Merge a 2 3 4 7 9 b 1 5 6 8 10 c 1 2 3 4 5 6 7 8 9 10 Merge Sort We can create a sort in the following way: If there is only 1 element in the list do nothing Otherwise break the list into two nearly even parts a and b Sort each part Merge the two together How do we sort each part? Recursively! 7 9 2 4 3 8 10 1 5 6 Merge Sort We can create a sort in the following way: If there is only 1 element in the list do nothing Otherwise break the list into two nearly even parts a and b Sort each part Merge the two together How do we sort each part? Recursively! 7 9 2 4 3 8 10 1 5 6 Merge Sort We can create a sort in the following way: If there is only 1 element in the list do nothing Otherwise break the list into two nearly even parts a and b Sort each part Merge the two together How do we sort each part? Recursively! 2 3 4 7 9 1 5 6 8 10 Merge Sort We can create a sort in the following way: If there is only 1 element in the list do nothing Otherwise break the list into two nearly even parts a and b Sort each part Merge the two together How do we sort each part? Recursively! 1 2 3 4 5 6 7 8 9 10 template <class T> void mergeSort(T & x) { if (x.size() <= 1) return; int i; T a, b; a.resize(x.size()/2); b.resize(x.size() a.size()); for(i=0; i< a.size(); i++) a[ i ] = x[ i ]; for(i=0; i< b.size(); i++) b[ i ] = x[ a.size()+i ]; mergeSort(a); mergeSort(b); merge(a, b, x); return; } Merge Sort Exercise 3 Which parts of the code correspond to the following functions? 1 It recursively calls the routine. 2 It provides a termination condition. 3 It copies the data to the sublists. 4 It aligns the two sublists. 5 It allocates memory for the sublists. template <class T> void mergeSort(T & x) { if (x.size() <= 1) return; int i; T a, b; a.resize(x.size()/2); b.resize(x.size() a.size()); for(i=0; i< a.size(); i++) a[ i ] = x[ i ]; for(i=0; i< b.size(); i++) b[ i ] = x[ a.size()+i ]; mergeSort(a); mergeSort(b); merge(a, b, x); } Merge Sort if the size of x is 1 or 0 then there is no need to sort template <class T> void mergeSort(T & x) { if (x.size() <= 1) return; int i; T a, b; a.resize(x.size()/2); b.resize(x.size() a.size()); Merge Sort Otherwise split the list into two sub-lists that are each half or nearly-half for(i=0; i< a.size(); i++) a[ i ] = x[ i ]; the original list for(i=0; i< b.size(); i++) b[ i ] = x[ a.size()+i ]; mergeSort(a); mergeSort(b); merge(a, b, x); } template <class T> void mergeSort(T & x) { if (x.size() <= 1) return; int i; T a, b; a.resize(x.size()/2); b.resize(x.size() a.size()); for(i=0; i< a.size(); i++) a[ i ] = x[ i ]; for(i=0; i< b.size(); i++) b[ i ] = x[ a.size()+i ]; mergeSort(a); mergeSort(b); merge(a, b, x); } Merge Sort Copy the original list into the two sublists template <class T> void mergeSort(T & x) { if (x.size() <= 1) return; int i; T a, b; a.resize(x.size()/2); b.resize(x.size() a.size()); for(i=0; i< a.size(); i++) a[ i ] = x[ i ]; for(i=0; i< b.size(); i++) b[ i ] = x[ a.size()+i ]; mergeSort(a); mergeSort(b); merge(a, b, x); } Merge Sort Sort each half template <class T> void mergeSort(T & x) { if (x.size() <= 1) return; int i; T a, b; a.resize(x.size()/2); b.resize(x.size() a.size()); for(i=0; i< a.size(); i++) a[ i ] = x[ i ]; for(i=0; i< b.size(); i++) b[ i ] = x[ a.size()+i ]; mergeSort(a); mergeSort(b); merge(a, b, x); } Merge Sort Merge them Merge Sort 7 9 2 4 3 8 10 1 5 6 Merge Sort 7 9 2 4 3 8 10 1 5 6 split Merge Sort 7 9 2 4 3 8 10 1 5 6 7 9 2 4 3 sort Merge Sort 7 9 2 4 3 8 10 1 5 6 7 9 2 4 3 split Merge Sort 7 9 2 4 3 8 10 1 5 6 7 9 2 4 3 7 9 sort Merge Sort 7 9 2 4 3 8 10 1 5 6 7 9 2 4 3 7 9 split Merge Sort 7 9 2 4 3 8 10 1 5 6 7 9 2 4 3 merge Merge Sort 7 9 2 4 3 8 10 1 5 6 7 9 2 4 3 2 4 3 sort Merge Sort 7 9 2 4 3 8 10 1 5 6 7 9 2 4 3 2 4 3 split Merge Sort 7 9 2 4 3 8 10 1 5 6 7 9 2 4 3 2 4 3 4 3 sort Merge Sort 7 9 2 4 3 8 10 1 5 6 7 9 2 4 3 2 4 3 4 3 split Merge Sort 7 9 2 4 3 8 10 1 5 6 7 9 2 4 3 2 3 4 merge Merge Sort 7 9 2 4 3 8 10 1 5 6 7 9 2 3 4 merge Merge Sort 2 3 4 7 9 8 10 1 5 6 merge Merge Sort 2 3 4 7 9 8 10 1 5 6 sort 8 10 1 5 6 Merge Sort 2 3 4 7 9 8 10 1 5 6 split 8 10 1 5 6 Merge Sort 2 3 4 7 9 8 10 1 5 6 sort 8 10 1 5 6 8 10 Merge Sort 2 3 4 7 9 8 10 1 5 6 split 8 10 1 5 6 8 10 Merge Sort 2 3 4 7 9 8 10 1 5 6 merge 8 10 1 5 6 Merge Sort 2 3 4 7 9 8 10 1 5 6 sort 8 10 1 5 6 1 5 6 Merge Sort 2 3 4 7 9 8 10 1 5 6 split 8 10 1 5 6 1 5 6 Merge Sort 2 3 4 7 9 8 10 1 5 6 sort 8 10 1 5 6 1 5 6 5 6 Merge Sort 2 3 4 7 9 8 10 1 5 6 split 8 10 1 5 6 1 5 6 5 6 Merge Sort 2 3 4 7 9 8 10 1 5 6 merge 8 10 1 5 6 1 5 6 Merge Sort 2 3 4 7 9 8 10 1 5 6 merge 8 10 1 5 6 Merge Sort 2 3 4 7 9 1 5 6 8 10 merge Merge Sort 1 2 3 4 5 6 7 8 9 10 merge Merge Sort How many comparisons are made? Each Merge is N comparisons if the list is N long. So the last merge takes N The merges before that are 2 merges of approximately N/2 each for a total of N The merges before that are 4 merges of N/ 4 each Merge Sort 2 3 4 7 9 8 10 1 5 6 7 9 2 4 3 8 10 1 5 6 7 9 2 4 3 8 10 1 5 6 After N 4 3 splitting the list log2N times we have divided it into its individual pieces log2 (10) =3.32... This 5 6 algorithm requires N log(N) comparisons ...
View Full Document

This note was uploaded on 04/02/2008 for the course ENGR 101 taught by Professor Ringenberg during the Fall '07 term at University of Michigan.

Ask a homework question - tutors are online