Merge Sort Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science University of Wisconsin.

Slides:



Advertisements
Similar presentations
Divide-and-Conquer 7 2  9 4   2   4   7
Advertisements

AVL Trees1 Part-F2 AVL Trees v z. AVL Trees2 AVL Tree Definition (§ 9.2) AVL trees are balanced. An AVL Tree is a binary search tree such that.
© 2004 Goodrich, Tamassia Merge Sort1 7 2  9 4   2  2 79  4   72  29  94  4.
© 2004 Goodrich, Tamassia Merge Sort1 7 2  9 4   2  2 79  4   72  29  94  4.
Data Structures Lecture 9 Fang Yu Department of Management Information Systems National Chengchi University Fall 2010.
1 Divide-and-Conquer CSC401 – Analysis of Algorithms Lecture Notes 11 Divide-and-Conquer Objectives: Introduce the Divide-and-conquer paradigm Review the.
Merge Sort1 Part-G1 Merge Sort 7 2  9 4   2  2 79  4   72  29  94  4.
Merge Sort1 7 2  9 4   2  2 79  4   72  29  94  4.
Insertion Sort. Selection Sort. Bubble Sort. Heap Sort. Merge-sort. Quick-sort. 2 CPSC 3200 University of Tennessee at Chattanooga – Summer 2013 © 2010.
© 2004 Goodrich, Tamassia Quick-Sort     29  9.
© 2004 Goodrich, Tamassia QuickSort1 Quick-Sort     29  9.
1 Sorting Problem: Given a sequence of elements, find a permutation such that the resulting sequence is sorted in some order. We have already seen: –Insertion.
Quick-Sort     29  9.
© 2004 Goodrich, Tamassia Quick-Sort     29  9.
Divide-and-Conquer1 7 2  9 4   2  2 79  4   72  29  94  4.
Divide-and-Conquer1 7 2  9 4   2  2 79  4   72  29  94  4.
Chapter 4: Divide and Conquer The Design and Analysis of Algorithms.
Divide-and-Conquer1 7 2  9 4   2  2 79  4   72  29  94  4 Modified by: Daniel Gomez-Prado, University of Massachusetts Amherst.
MergeSort Source: Gibbs & Tamassia. 2 MergeSort MergeSort is a divide and conquer method of sorting.
Sorting.
Divide-and-Conquer 7 2  9 4   2   4   7
Divide-and-Conquer1 7 2  9 4   2  2 79  4   72  29  94  4.
Merge Sort. What Is Sorting? To arrange a collection of items in some specified order. Numerical order Lexicographical order Input: sequence of numbers.
File Organization and Processing Week 13 Divide and Conquer.
Sorting Fun1 Chapter 4: Sorting     29  9.
Lecture10: Sorting II Bohyung Han CSE, POSTECH CSED233: Data Structures (2014F)
General Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science University of Wisconsin.
Review and Prepare for Test 3 CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and Computer Science.
Bubble Sort Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and.
Hanoi Towers Big Oh Recursion Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science.
Searching CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and Computer Science University of Wisconsin.
Priority Queues and Sorting CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and Computer Science.
+ David Kauchak cs312 Review. + Midterm Will be posted online this afternoon You will have 2 hours to take it watch your time! if you get stuck on a problem,
© 2004 Goodrich, Tamassia Quick-Sort     29  9.
© 2004 Goodrich, Tamassia Merge Sort1 7 2  9 4   2  2 79  4   72  29  94  4.
Quicksort Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and Computer.
1 More Merge Sort Java implementation Time complexity Generic merging and sets.
Priority Queues and Heaps Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science University.
Reading from a file, Sorting, and a little Searching Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics,
1 Merge Sort 7 2  9 4   2  2 79  4   72  29  94  4.
Towers of Hanoi Move n (4) disks from pole A to pole B such that a larger disk is never put on a smaller disk A BC ABC.
Trees Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science University of Wisconsin.
Merge Sort 1/12/2018 5:48 AM Merge Sort 7 2   7  2  2 7
Advanced Sorting 7 2  9 4   2   4   7
Advanced Algorithms Analysis and Design
Chapter 11 Sorting Acknowledgement: These slides are adapted from slides provided with Data Structures and Algorithms in C++, Goodrich, Tamassia and Mount.
Merge Sort 1/12/2018 9:44 AM Presentation for use with the textbook Data Structures and Algorithms in Java, 6th edition, by M. T. Goodrich, R. Tamassia,
Divide-and-Conquer 6/30/2018 9:16 AM
Quick-Sort 9/12/2018 3:26 PM Presentation for use with the textbook Data Structures and Algorithms in Java, 6th edition, by M. T. Goodrich, R. Tamassia,
MergeSort Source: Gibbs & Tamassia.
More on Merge Sort CS 244 This presentation is not given in class
Objectives Introduce different known sorting algorithms
Divide-and-Conquer 7 2  9 4   2   4   7
Review and Prepare for Test 2
Sorting And Searching CSE116A,B 2/23/2019 B.Ramamurthy.
Merge Sort 2/23/ :15 PM Merge Sort 7 2   7  2   4  4 9
Merge Sort 2/24/2019 6:07 PM Merge Sort 7 2   7  2  2 7
Quick-Sort 2/25/2019 2:22 AM Quick-Sort     2
Copyright © Aiman Hanna All rights reserved
Copyright © Aiman Hanna All rights reserved
Quick-Sort 4/8/ :20 AM Quick-Sort     2 9  9
Divide-and-Conquer 7 2  9 4   2   4   7
Sorting And Searching CSE116A,B 4/7/2019 B.Ramamurthy.
Merge Sort 4/10/ :25 AM Merge Sort 7 2   7  2   4  4 9
Quick-Sort 4/25/2019 8:10 AM Quick-Sort     2
Divide-and-Conquer 7 2  9 4   2   4   7
Merge Sort 5/30/2019 7:52 AM Merge Sort 7 2   7  2  2 7
Data Structures and Algorithms CS 244
Divide-and-Conquer 7 2  9 4   2   4   7
Presentation transcript:

Merge Sort Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science University of Wisconsin – Stout Based on the book: Data Structures and Algorithms in C++ (Goodrich, Tamassia, Mount) Some content from Data Structures Using C++ (D.S. Malik)

Previously Sorts Already Seen Insertion Sort Selection Sort Bubble Sort Related Linear (sequential) Search Binary Search

Merge Sort We are jumping ahead in the book Chap 11.1 Mostly so we don’t run out of time and miss this But also because it fits in several different ways Goes with sorting Goes with Big Oh Shows how to think using binary trees Example of application before theory And then we will jump back to Chap 6

Merge Sort (the Picture) 7 2  9 4   2  2 79  4   72  29  94  4

Merge Sort Algorithm Merge sort is based on the divide-and-conquer paradigm. It consists of three steps: – Divide: partition input sequence S into two sequences S 1 and S 2 of about n  2 elements each – Recur: recursively sort S 1 and S 2 – Conquer: merge S 1 and S 2 into a unique sorted sequence Algorithm mergeSort(S, C) Input sequence S, comparator C Output sequence S sorted according to C if S.size() > 1 { (S 1, S 2 ) := partition(S, S.size()/2) S 1 := mergeSort(S 1, C) S 2 := mergeSort(S 2, C) S := merge(S 1, S 2 ) } return(S)

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Start at the top node --- or rather the ROOT computer science trees grow upside down

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Partition the numbers into 2 sets (left half and right half) 

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Create child nodes 

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call MergeSort on ‘left’ child Results in partitioning it into 2 sets (left and right)   9 4

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call MergeSort on ‘left’ child Results in partitioning it into 2 sets (left and right)   9 4

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Create 2 child nodes  

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call MergeSort on ‘left’ child  

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Partition into 2 sets    2 9 4

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Partition into 2 sets, left and right    2 9 4

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Create 2 child nodes   

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call Merge Sort on ‘left’ child   

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Single element is already ordered by definition, results in     7

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call Merge Sort on ‘right’ child     7 2

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Single element is already ordered by definition, results in     7 2  2

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call Merge on the two sequences: { 7 } and { 2 }     7 2  2

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call Merge on the two sequences: { 7 } and { 2 }    2   7 2  2

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call Merge on the two sequences: { 7 } and { 2 }    2   7 2  2

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Results in ordered sequence of { 2 7 }    2   7 2  2

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call MergeSort on ‘right’ child    2   7 2  2 9 4

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Partition and create child nodes    2   7 2  2 9  4 94

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call MergeSort on left child    2   7 2  2 9  4 9  9 4

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call MergeSort on right child    2   7 2  2 9  4 9  94  4

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Merge Sequences: { 9 } and { 4 }    2   7 2  2 9  4   94  4

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Merge Sequences: { 2 7 } and { 4 9 }    2   7 2  2 9  4   94  4

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Merge Sequences: { 2 7 } and { 4 9 }   9 4  2 7  2   7 2  2 9  4   94  4

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Merge Sequences: { 2 7 } and { 4 9 }   9 4   2   7 2  2 9  4   94  4

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Merge Sequences: { 2 7 } and { 4 9 }   9 4   2   7 2  2 9  4   94  4

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Merge Sequences: { 2 7 } and { 4 9 }   9 4   2   7 2  2 9  4   94  4

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Result is{ }   9 4   2   7 2  2 9  4   94  4

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call MergeSort on right side   9 4   2   7 2  2 9  4   94 

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Partition and create children   9 4   2   7 2  2 9  4   94  

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call MergeSort on left child   9 4   2   7 2  2 9  4   94  

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Partition and create child nodes   9 4   2   7 2  2 9  4   94    8 38

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call MergeSort on left child   9 4   2   7 2  2 9  4   94     3

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call MergeSort on right child   9 4   2   7 2  2 9  4   94    8 3  38  8

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Merge Results   9 4   2   7 2  2 9  4   94    8   38  8

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call MergeSort on right child   9 4   2   7 2  2 9  4   94    8   38  8 6 1

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Partition and create children   9 4   2   7 2  2 9  4   94    8   38  8 6  1 61

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call MergeSort on left child   9 4   2   7 2  2 9  4   94    8   38  8 6   6

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Call MergeSort on right child   9 4   2   7 2  2 9  4   94    8   38  8 6  1 6  61  1

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Merge results { 6 } and { 1 }   9 4   2   7 2  2 9  4   94    8   38  86  61  1 6  1  1 6

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Merge results { 3 8 } and { 1 6 }   9 4   2   7 2  2 9  4   94  4 3  8   38  86  61  1 6  1   6 1 

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Merge results { } and { } 7 2  9 4   2   7 2  2 9  4   94  4 3  8   38  86  61  1 6  1   6 1   

Merge Sort Execution Tree An execution of merge-sort is depicted by a binary tree Merge results { } and { } 7 2  9 4   2   7 2  2 9  4   94  4 3  8   38  86  61  1 6  1   6 1   

MergeSort: Another Tree Layout You may also see MergeSort Trees that instead of reversing direction back up the tree continue down merging the branches as they go

End Example Walk Through Next In Class Activity

Complete the following MergeSort tree      C R P G B H Q A

In Class Activity First Step: Divide into two parts. Stay with Left      C R P G B H Q A C R P G B H Q A

In Class Activity Second Step: Divide again. Stay with left      C R P G B H Q A C R  P G B H Q A C R

In Class Activity Third Step: Divide again. Stay with Left half      C R P G B H Q A B H Q A C  R C C R  P G

In Class Activity Fourth Step: Go with Right half now      C R P G B H Q A B H Q A C  R R C C C R  P G

In Class Activity Fifth Step: Merge { C } and { R }      C R P G B H Q A B H Q A R C C R C R  P G C  R C R

In Class Activity Keep Going      C R P G B H Q A B H Q A R C C R Pause Here For Students To Complete C R  P G C  R CR

Class Exercise Complete the following MergeSort tree C R  P G  C G P RB H Q A  A B H Q C  R  C RP G  G PB H  B HQ A  A Q C  CR  RP  PG  GB  BH  HQ  QA  A C R P G B H Q A Enhanced Version

Merge Sort Merge sort is based on the divide-and-conquer paradigm. It consists of three steps: – Divide: partition input sequence S into two sequences S 1 and S 2 of about n  2 elements each – Recur: recursively sort S 1 and S 2 – Conquer: merge S 1 and S 2 into a unique sorted sequence Algorithm mergeSort(S, C) Input sequence S, comparator C Output sequence S sorted according to C if S.size() > 1 { (S 1, S 2 ) := partition(S, S.size()/2) S 1 := mergeSort(S 1, C) S 2 := mergeSort(S 2, C) S := merge(S 1, S 2 ) } return(S)

Runtime of Merge Sort ? Merge sort is based on the divide-and-conquer paradigm. It consists of three steps: – Divide: partition input sequence S into two sequences S 1 and S 2 of about n  2 elements each – Recur: recursively sort S 1 and S 2 – Conquer: merge S 1 and S 2 into a unique sorted sequence Algorithm mergeSort(S, C) Input sequence S, comparator C Output sequence S sorted according to C if S.size() > 1 { (S 1, S 2 ) := partition(S, S.size()/2) S 1 := mergeSort(S 1, C) S 2 := mergeSort(S 2, C) S := merge(S 1, S 2 ) } return(S) O( ? )

Runtime of Merge Sort ? Merge sort is based on the divide-and-conquer paradigm. It consists of three steps: – Divide: partition input sequence S into two sequences S 1 and S 2 of about n  2 elements each – Recur: recursively sort S 1 and S 2 – Conquer: merge S 1 and S 2 into a unique sorted sequence Algorithm mergeSort(S, C) Input sequence S, comparator C Output sequence S sorted according to C if S.size() > 1 { (S 1, S 2 ) := partition(S, S.size()/2) S 1 := mergeSort(S 1, C) S 2 := mergeSort(S 2, C) S := merge(S 1, S 2 ) } return(S) O( 1 ) O( ? ) Divide Step is O(1) if using arrays and NOT making temporary copies middleIndex = minIndex + (maxIndex - minIndex)/2 Aside: If using a list or making temporary copies using brute force approach results in O(n)  Because we have to copy or walk through n elements

Runtime of Merge Sort ? Merge sort is based on the divide-and-conquer paradigm. It consists of three steps: – Divide: partition input sequence S into two sequences S 1 and S 2 of about n  2 elements each – Recur: recursively sort S 1 and S 2 – Conquer: merge S 1 and S 2 into a unique sorted sequence Algorithm mergeSort(S, C) Input sequence S, comparator C Output sequence S sorted according to C if S.size() > 1 { (S 1, S 2 ) := partition(S, S.size()/2) S 1 := mergeSort(S 1, C) S 2 := mergeSort(S 2, C) S := merge(S 1, S 2 ) } return(S) O( 1 ) O( TBD ) O( ? ) Recursive Step: Assume initially there are N elements. Then denote the time for mergeSort to be T(N) Because we recursively call mergeSort T(N) will have to be >= T(N/2) + T(N/2)

Runtime of Merge Sort ? Merge sort is based on the divide-and-conquer paradigm. It consists of three steps: – Divide: partition input sequence S into two sequences S 1 and S 2 of about n  2 elements each – Recur: recursively sort S 1 and S 2 – Conquer: merge S 1 and S 2 into a unique sorted sequence Algorithm mergeSort(S, C) Input sequence S, comparator C Output sequence S sorted according to C if S.size() > 1 { (S 1, S 2 ) := partition(S, S.size()/2) S 1 := mergeSort(S 1, C) S 2 := mergeSort(S 2, C) S := merge(S 1, S 2 ) } return(S) O( 1 ) O( TBD ) O( ? ) Conquer Step: For this we need to understand the support function merge

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND Example Run This a A This a B

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND Example Run This a S

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND Example Run

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND Example Run

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND Example Run

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND Example Run

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND Example Run

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND Example Run

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND Example Run

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND Example Run

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND Example Run

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND That concludes the example run of a merge But what is the run time of the algorithm (to the right) ?

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND n/2

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND n/2 + n/2

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND n/2 + n/2

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND n/2 + n/2

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND n/2 + n/2

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND n/2 + n/2

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND n/2 + n/2 + 1

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND n/2 + n/ n + 1

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND 3 n + 1

The Merge Part (conquer) The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND 3 n + 1

Conclusion O(n) Support Function Merge The conquer step of merge- sort consists of merging two sorted sequences A and B into a sorted sequence S containing the union of the elements of A and B Merging two sorted sequences, each with n  2 elements and implemented by means of a doubly linked list, takes O(n) time M(n) = O(n) Algorithm merge(A, B) Input sequences A and B with n/2 elements each Output sorted sequence of A  B S  empty sequence while  A.isEmpty()   B.isEmpty() if A.first() < B.first() S.insertLast(A.removeFirst()) else S.insertLast(B.removeFirst()) while  A.isEmpty() S.insertLast(A.removeFirst()) while  B.isEmpty() S.insertLast(B.removeFirst()) return S Notice:  means NOT Notice:  means AND Repeat

Merge Sort Merge sort is based on the divide-and-conquer paradigm. It consists of three steps: – Divide: partition input sequence S into two sequences S 1 and S 2 of about n  2 elements each – Recur: recursively sort S 1 and S 2 – Conquer: merge S 1 and S 2 into a unique sorted sequence Algorithm mergeSort(S, C) Input sequence S, comparator C Output sequence S sorted according to C if S.size() > 1 { (S 1, S 2 ) := partition(S, S.size()/2) S 1 := mergeSort(S 1, C) S 2 := mergeSort(S 2, C) S := merge(S 1, S 2 ) } return(S) O( 1 ) O( TBD ) O( n ) Per previous slides, we just calculated this

Merge Sort Merge sort is based on the divide-and-conquer paradigm. It consists of three steps: – Divide: partition input sequence S into two sequences S 1 and S 2 of about n  2 elements each – Recur: recursively sort S 1 and S 2 – Conquer: merge S 1 and S 2 into a unique sorted sequence Algorithm mergeSort(S, C) Input sequence S, comparator C Output sequence S sorted according to C if S.size() > 1 { (S 1, S 2 ) := partition(S, S.size()/2) S 1 := mergeSort(S 1, C) S 2 := mergeSort(S 2, C) S := merge(S 1, S 2 ) } return(S) O( 1 ) O( TBD ) O( n ) Still must work out this recursive call stuff

What we have so far By definition T(N) = # of comparisons to mergesort an input size of N So T(N) = partition time + time left half + time right half + time to merge = constant + T( N/2 ) + T( N/2 ) + N Thus Mergesort recurrence: T(N) = 2*T( N/2 ) + N for N > 1, and T(1) = 0  takes zero time to sort 1 thing also let’s assume N is a power of 2 Claim T(N) = N lg N Can we “prove” it ? Recall: lg N denotes log 2 N DivideRecurConquer

The Tree Proof The height h of the merge-sort tree is O(log 2 n) at each recursive call we divide the sequence in half, The work done at each level is O(n) At level i, we partition and merge 2 i sequences of size n  2 i Thus, the total running time of merge-sort is O(n log 2 n)

The Tree Proof The height h of the merge-sort tree is O(log 2 n) at each recursive call we divide the sequence in half, The work done at each level is O(n) At level i, we partition and merge 2 i sequences of size n  2 i Thus, the total running time of merge-sort is O(n log 2 n) lg n

= n The Tree Proof The height h of the merge-sort tree is O(lg n) at each recursive call we divide the sequence in half, The work done at each level is O(n) At level i, we partition and merge 2 i sequences of size n  2 i Thus, the total running time of merge-sort is O(n lg n) n T(n) T(n/2) + 2(n/2) lg n = n

The Tree Proof The height h of the merge-sort tree is O(lg n) at each recursive call we divide the sequence in half, The work done at each level is O(n) At level i, we partition and merge 2 i sequences of size n  2 i Thus, the total running time of merge-sort is O(n lg n) n T(n) T(n/2) T(n/4) + 2(n/2) lg n : = n + 4(n/4)

= n The Tree Proof The height h of the merge-sort tree is O(lg n) at each recursive call we divide the sequence in half, The work done at each level is O(n) At level i, we partition and merge 2 i sequences of size n  2 i Thus, the total running time of merge-sort is O(n lg n) n T(n) T(n/2) T(n/4) + 2(n/2) lg n T(n / 2 k ) : + 2 k (n/2 k ) : = n + 4(n/4)

= n The Tree Proof The height h of the merge-sort tree is O(lg n) at each recursive call we divide the sequence in half, The work done at each level is O(n) At level i, we partition and merge 2 i sequences of size n  2 i Thus, the total running time of merge-sort is O(n lg n) n T(n) T(n/2) T(n/4) + 2(n/2) lg n T(n / 2 k ) : + 2 k (n/2 k ) T(2) : + (n/2)*2 = n + 4(n/4)

The Tree Proof The height h of the merge-sort tree is O(lg n) The work done at each level is O(n) Thus, the total running time of merge-sort is O(n lg n) T(n) T(n/2) T(n/4) lg n T(n / 2 k ) T(2) = n n + 2(n/2) : + 2 k (n/2 k ) : + (n/2)*2 = n + 4(n/4)

Telescoping Proof T(N) = 2 * T(N/2) + N Begin by dividing both sides by N T(N) / N = 2 * T(N/2) / N + 1 = T(N/2) / (N/2) + 1 by algebra (*2 same as divide by (1/2) ) = T(N/4) / (N/4) telescope (apply to first term) = T(N/8) / (N/8) telescope (apply to first term) : = T(N/N) / (N/N) … + 1 stop telescoping T(N/N) = T(1) = 0 = lg N that is T(N) / N = lg N so T(N) = N lg N Given T(N) = 2T(N/2) + N Prove T(N) = N lg N for N>1, and also given T(1) = 0 Recall: lg N denotes log 2 N

Telescoping Proof T(N) = 2 * T(N/2) + N Begin by dividing both sides by N T(N) / N = 2 * T(N/2) / N + 1 = T(N/2) / (N/2) + 1 by algebra (*2 same as divide by (1/2) ) = T(N/4) / (N/4) telescope (apply to first term) = T(N/8) / (N/8) telescope (apply to first term) : = T(N/N) / (N/N) … + 1 stop telescoping T(N/N) = T(1) = 0 = lg N that is T(N) / N = lg N so T(N) = N lg N Given T(N) = 2T(N/2) + N Prove T(N) = N lg N for N>1, and also given T(1) = 0 Recall: lg N denotes log 2 N T(N/2) / (N/2) = 2 T( (N/2) / 2) / (N/2) + 1 = 2 T( N / 4) / (N/2) + 1 = T( N / 4) / ( (N/2) * (1/2) ) + 1 = T( N/ 4) / (N / 4) + 1 telescope (apply to first term) 2 * ( T(N/2) / N ) = ( T(N/2) / N ) / ( 1/ 2) = T(N/2) / ( N * (1/2) ) = T(N/2) / ( N /2) by algebra (*2 same as divide by (1/2) )

Summary of Sorting Algorithms (so far) AlgorithmTimeNotes Selection SortO(n 2 )Slow, in-place For small data sets Insertion SortO(n 2 )Slow, in-place For small data sets Bubble SortO(n 2 )Slow, in-place For small data sets Heap SortO(nlog n)Fast, in-place For large data sets Merge SortO(n lg n)Fast, sequential data access For huge data sets

Graded In-Class Activity: MergeSort Using std::vector Implement MergeSort on an vector of type int See algorithms on previous slides for basic idea Do NOT use std::list  use std::vector Starter Code may be available on D2L ICA212_MergeSort.cpp On an INDIVIDUAL basis turn in resulting code for possible bonus points on an assignment May work as group But each individual must turn in Identify any one else you worked with in the code comments

Cowtoth C hallenge O n W hich TO TH ink You are given a Singly Linked List of integers e.g. nodeType * You do NOT know how many items are in the list Write a function that has input: a pointer to the first node in the list, pList output: a pointer to the middle node of the list restriction: the function may use only 3 variables nodeType *pList (the input parameter – not to be changed) nodeType *middle (the return value) nodeType *current (a pointer for temporary use) Assume each node in the list has a next pointer i.e. Given nodeType *pointer = pList pList->next will give a pointer to the next node or NULL if there is no next node

Moving on to Trees Tree Definitions and ADT (§7.1) Tree Traversal Algorithms for General Trees (preorder and postorder) (§7.2) BinaryTrees (§7.3) Data structures for trees (§7.1.4 and §7.3.4) Traversals of Binary Trees (preorder, inorder, postorder) (§7.3.6) Euler Tours (§7.3.7)

The End of This Part End