Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

Recursion, Mergesort, and Quicksort Algorithms in Java, Slides of Design

An introduction to recursion and the implementation of Mergesort and Quicksort algorithms in Java, including divide and conquer, pivot selection, and in-place partitioning. It also discusses the advantages and disadvantages of each algorithm and their time complexity.

Typology: Slides

2021/2022

Uploaded on 09/27/2022

jacksonhh
jacksonhh 🇬🇧

4.2

(23)

34 documents

1 / 47

Toggle sidebar

Related documents


Partial preview of the text

Download Recursion, Mergesort, and Quicksort Algorithms in Java and more Slides Design in PDF only on Docsity! cs2420 | Introduction to Algorithms and Data Structures | Spring 2015 MERGESORT & QUICKSORT 1 administrivia… 2 re⋅cur⋅sion [ri-kur-zhuh n] noun see recursion. 5 6 -recursion is a problem solving technique in which the solution is defined in terms of a simpler (or smaller) version of the problem -break the problem into smaller parts -solve the smaller problems -combine the results -a recursive method calls itself -some functions are easiest to define recursively -there must be at least on base case that can be computed without recursion -any recursive call must make progress towards the base case! sum(N) = sum(N-1) + N a simple example 7 sum(N) = sum(N-1) + N public static int sum(int n) { if(n == 1) return 1; return sum(n-1) + n; } how can we solve the same problem without recursion? which is better, the recursive solution or the alternative? fix to handle zero or negative values. . . 4 recursion rules 1.always have at least one case that can be solved without using recursion 2.any recursive call must progress toward a base case 3.always assume that the recursive call works, and use this assumption to design your algorithms 4.never duplicate work by solving the same instance of a problem in separate recursive calls 10 today… 11 12 -mergesort -quicksort -midterm stuff mergesort 1)divide the array in half 2)sort the left half 3)sort the right half 4)merge the two halves together 15 what is missing here? how do we sort? can we avoid sorting? how? mergesort 1)divide the array in half 2)sort the left half 3)sort the right half 4)merge the two halves together 16 what does this look like? 2) take the left half, and go back to step 1 3) take the right half, and go back to step 1 until??? until??? void mergesort(int[] arr, int left, int right) { int mid = (left + right) / 2; mergsort(arr, left, mid); mergsort(arr, mid+1, right); merge(arr, left, mid+1, right); } 17 divide conquer what are we missing? void mergesort(int[] arr, int left, int right) { // arrays of size 1 are already sorted if(start >= end) return; int mid = (left + right) / 2; mergsort(arr, left, mid); mergsort(arr, mid+1, right); merge(arr, left, mid+1, right); } 20 divide conquer what is the complexity of MERGESORT? A) c B) log N C) N D) N log N E) N2 F) N3 is this the worst || average || best-case? merging sorted arrays -easy concept, tricky code… -lots of special cases: -keep track of two indices to step through both arrays (the “front” of each array) -indices do not necessarily move at the same speed -have to stop the loop when either index reaches the end of their array -the two arrays are not necessarily the same size -what to do when you reach the end of one array but not the other? -copy from temp back into the array 21 void Merge(int[] arr, start, mid, end) { // create temp array for holding merged arr int[] temp = new int[end – start + 1]; int i1 = 0, i2 = mid; while(i1 < mid && i2 < end) { put smaller of arr[i1], arr[i2] into temp; } copy anything left over from larger half to temp; copy temp over to arr; } 22 Is there anything we should do different? mergesort variation -it is a good idea to invoke insertion sort when the subarray size reaches a small enough threshold -why??? -HINT: what is the complexity of insertion sort? of mergesort? what are other runtime considerations? -the real threshold depends on several things: -hardware / OS / compiler -input characteristics 25 quicksort 26 another divide and conquer quicksort 1)select an item in the array to be the pivot 2)partition the array so that all items less than the pivot are to the left of the pivot, and all the items greater than the pivot are to the right 3)sort the left half 4)sort the right half 27 what do you notice? NOTE: after partitioning, the pivot is in it’s final position! void quicksort(int[] arr, int left, int right) { // arrays of size 1 are already sorted if(start >= end) return; int pivot_index = partition(arr, left, right); quicksort(arr, left, pivot_index-1); quicksort(arr, pivot_index+1, right); } 30 what is the divide step? what is the conquer step? quick note… -a huge benefit of quicksort is that it can be done in-place -ie. you can do the sort within the original array -mergesort requires an extra, temporary array for merging -however, in-place partitioning for quicksort requires some careful thought… 31 in-place partitioning 1)select an item in the array to be the pivot 2)swap the pivot with the last item in the array (just get it out of the way) 3)step from left to right until we find an item > pivot -this item needs to be on the right of the partition 4)step from right to left until we find an item < pivot -this item needs to be on the left of the partition 5)swap items 6)continue until left and right stepping cross 7)swap pivot with left stepping item 32 what does this look like? choosing a pivot -any nonrandom pivot selection has some devious input that causes O(N2) -trade-off between quality of pivot and time to select -selection cost should always be O(c) -ie. it should not depend on N! 35 cs2420 | Introduction to Algorithms and Data Structures | Spring 2015 MERGESORT & QUICKSORT 1 administrivia… 2 re⋅cur⋅sion [ri-kur-zhuh n] noun see recursion. 5 6 -recursion is a problem solving technique in which the solution is defined in terms of a simpler (or smaller) version of the problem -break the problem into smaller parts -solve the smaller problems -combine the results -a recursive method calls itself -some functions are easiest to define recursively -there must be at least on base case that can be computed without recursion -any recursive call must make progress towards the base case! sum(N) = sum(N-1) + N a simple example 7 sum(N) = sum(N-1) + N public static int sum(int n) { if(n == 1) return 1; return sum(n-1) + n; } how can we solve the same problem without recursion? which is better, the recursive solution or the alternative? fix to handle zero or negative values. . . 4 recursion rules 1.always have at least one case that can be solved without using recursion 2.any recursive call must progress toward a base case 3.always assume that the recursive call works, and use this assumption to design your algorithms 4.never duplicate work by solving the same instance of a problem in separate recursive calls 10 today… 11 12 -mergesort -quicksort -midterm stuff mergesort 1)divide the array in half 2)sort the left half 3)sort the right half 4)merge the two halves together 15 what is missing here? how do we sort? can we avoid sorting? how? mergesort 1)divide the array in half 2)sort the left half 3)sort the right half 4)merge the two halves together 16 what does this look like? 2) take the left half, and go back to step 1 3) take the right half, and go back to step 1 until??? until??? void mergesort(int[] arr, int left, int right) { int mid = (left + right) / 2; mergsort(arr, left, mid); mergsort(arr, mid+1, right); merge(arr, left, mid+1, right); } 17 divide conquer what are we missing? void mergesort(int[] arr, int left, int right) { // arrays of size 1 are already sorted if(start >= end) return; int mid = (left + right) / 2; mergsort(arr, left, mid); mergsort(arr, mid+1, right); merge(arr, left, mid+1, right); } 20 divide conquer what is the complexity of MERGESORT? A) c B) log N C) N D) N log N E) N2 F) N3 is this the worst || average || best-case? merging sorted arrays -easy concept, tricky code… -lots of special cases: -keep track of two indices to step through both arrays (the “front” of each array) -indices do not necessarily move at the same speed -have to stop the loop when either index reaches the end of their array -the two arrays are not necessarily the same size -what to do when you reach the end of one array but not the other? -copy from temp back into the array 21 void Merge(int[] arr, start, mid, end) { // create temp array for holding merged arr int[] temp = new int[end – start + 1]; int i1 = 0, i2 = mid; while(i1 < mid && i2 < end) { put smaller of arr[i1], arr[i2] into temp; } copy anything left over from larger half to temp; copy temp over to arr; } 22 Is there anything we should do different? mergesort variation -it is a good idea to invoke insertion sort when the subarray size reaches a small enough threshold -why??? -HINT: what is the complexity of insertion sort? of mergesort? what are other runtime considerations? -the real threshold depends on several things: -hardware / OS / compiler -input characteristics 25 quicksort 26 another divide and conquer quicksort 1)select an item in the array to be the pivot 2)partition the array so that all items less than the pivot are to the left of the pivot, and all the items greater than the pivot are to the right 3)sort the left half 4)sort the right half 27 what do you notice? NOTE: after partitioning, the pivot is in it’s final position! void quicksort(int[] arr, int left, int right) { // arrays of size 1 are already sorted if(start >= end) return; int pivot_index = partition(arr, left, right); quicksort(arr, left, pivot_index-1); quicksort(arr, pivot_index+1, right); } 30 what is the divide step? what is the conquer step? quick note… -a huge benefit of quicksort is that it can be done in-place -ie. you can do the sort within the original array -mergesort requires an extra, temporary array for merging -however, in-place partitioning for quicksort requires some careful thought… 31 in-place partitioning 1)select an item in the array to be the pivot 2)swap the pivot with the last item in the array (just get it out of the way) 3)step from left to right until we find an item > pivot -this item needs to be on the right of the partition 4)step from right to left until we find an item < pivot -this item needs to be on the left of the partition 5)swap items 6)continue until left and right stepping cross 7)swap pivot with left stepping item 32 what does this look like? choosing a pivot -any nonrandom pivot selection has some devious input that causes O(N2) -trade-off between quality of pivot and time to select -selection cost should always be O(c) -ie. it should not depend on N! 35 quicksort complexity -performance of quick sort heavily depends on which array item is chosen as the pivot -best case: pivot partions the array into two equally- sized subarrays at each stage — O(N log N) -worst case: partition generates an empty subarray at each stage — O(N2) -average case: bound is O(N log N) -proof is quite involved, see the textbook if you are curious 36 quicksort vs mergesort 37 40 Sorting Review • a ! Best Average Worst Notes Selection Sort O(N2) O(N2) O(N2) Never used in practice Insertion Sort O(N) O(N2) O(N2) Takes advantage of “sortedness” Shellsort O(N log N) O(N1.25) O(N1.5) Depends on gap sizes Mergesort O(N log N) O(N log N) O(N log N) 2x space overhead, guaranteed O(N log N) Quicksort O(N log N) O(N log N) O(N^2) Depends on pivot sorting summary midterm 41 topics -Java basics -variables, types -control flow -reference types -classes, methods -OOP -inheritance -polymorphism -interfaces -super 42 test format -problems may be of the following types: -short answer -determining output of code -writing code -filling in missing code -multiple choice -true / false 45 next time… 46 47 -no lab on Monday -midterm on Tuesday in class -reading -chapter 17 -chapter 3 -http://opendatastructures.org/ods-java/ -homework -assignment 5 due Thursday
Docsity logo



Copyright © 2024 Ladybird Srl - Via Leonardo da Vinci 16, 10126, Torino, Italy - VAT 10816460017 - All rights reserved