Download as pdf or txt
Download as pdf or txt
You are on page 1of 22

Mergesort and Quicksort

@ 2016 Zanamwe N
Sorting algorithms
• Insertion, selection and bubble sort have
quadratic worst-case performance
• The faster comparison based algorithm ?
O(nlogn)

• Mergesort and Quicksort

@ 2016 Zanamwe N
Divide-and-Conquer
• Divide-and conquer is a general algorithm design paradigm:
– Divide: divide the input data S in two disjoint subsets S1 and S2
– Recur: solve the subproblems associated with S1 and S2
– Conquer: combine the solutions for S1 and S2 into a solution for S
• The base case for the recursion are subproblems of size 0 or 1

@ 2016 Zanamwe N
© 2016 Zanamwe
Merge Sort
• Merge sort divides the list in half to create two unsorted
lists. These two unsorted lists are sorted and merged by
recursively calling the merge-sort algorithm, until you get
a list of size 1.
• The algorithm is stable, as well as fast for large data sets.
• However, since it is not in-place, it requires much more
memory than many other algorithms.
• The space complexity is O(n) for arrays and O(ln n) for
linked lists.
• The best, average, and worst case times are all O(n ln n).

@ 2016 Zanamwe N
Merge Sort
• Apply divide-and-conquer to sorting problem
• Problem: Given n elements, sort elements into
non-decreasing order
• Divide-and-Conquer:
– If n=1 terminate (every one-element list is already
sorted)
– If n>1, partition elements into two or more sub-
collections; sort each; combine into a single sorted list
• How do we partition?
@ 2016 Zanamwe N
Partitioning
• Let’s try to achieve balanced partitioning
• A gets n/2 elements, B gets rest half
• Sort A and B recursively
• Combine sorted A and B using a process
called merge, which combines two sorted
lists into one
– How? We will see soon

@ 2016 Zanamwe N
Merge Sort Algorithm

The function
MergeOrdered simply
takes two ordered lists
and makes
them one.

@ 2016 Zanamwe N
MergeOrdered
def MergeOrdered(left,right):
if not left or not right: # if one list or both are empty it returns immediately
return left or right
result = []
i,j = 0,0
while i < len(left) and j < len(right):
if left[i] <= right[j]:
result.append(left[i])
i+=1
else :
result.append(right[j])
j+=1
if i < len(left) - 1 :
result+=left[i:]
elif j < len(right) - 1 :
result += right[j:]
return result @ 2016 Zanamwe N
Tutorial Question
• Using the MergeOrdered function defined
above
嗗Implement the Merge Sort algorithm using
recursion and test your algorithm

@ 2016 Zanamwe N
Example
• Partition into lists of size n/2

[10, 4, 6, 3, 8, 2, 5, 7]

[10, 4, 6, 3] [8, 2, 5, 7]

[10, 4] [6, 3] [8, 2] [5, 7]

[10] [4] [6][3] [8][2] [5][7]

@ 2016 Zanamwe N
Merging

[2, 3, 4, 5, 6, 7, 8, 10 ]

[3, 4, 6, 10] [2, 5, 7, 8]

[4, 10] [3, 6] [2, 8] [5, 7]

[10] [4] [6][3] [8][2] [5][7]


@ 2016 Zanamwe N
Spliting the List

@ 2016 Zanamwe N
Merging

@ 2016 Zanamwe N
Quicksort Algorithm
Given an array of n elements (e.g., integers):
• If array only contains one element, return
• Else
– pick one element to use as pivot.
– Partition elements into two sub-arrays:
• Elements less than or equal to pivot
• Elements greater than pivot
– Quicksort two sub-arrays
– Return results
@ 2016 Zanamwe N
Example
We are given array of n integers to sort:
40 20 10 80 60 50 7 30 100

@ 2016 Zanamwe N
Pick Pivot Element
There are a number of ways to pick the pivot element which include:
1. using the first element as the pivot
2. using the last element as the pivot
3. Set pivot equal to the median value of three elements from list/array:
1. median value = list[0], list[n/2], and list[n-1].

In this example, we will use the first element in the array:

40 20 10 80 60 50 7 30 100

@ 2016 Zanamwe N
Partitioning Array
Given a pivot, partition the elements of the array
such that the resulting array consists of:
1. One sub-array that contains elements >= pivot
2. Another sub-array that contains elements < pivot

The sub-arrays are stored in the original data array.

Partitioning loops through, swapping elements


below/above pivot.

@ 2016 Zanamwe N
20 10 7 30 40 80 60 50 100
[0] [1] [2] [3] [4] [5] [6] [7] [8]

20 10 7 30 40 80 60 50 100
[0] [1] [2] [3] [4] [5] [6] [7] [8]
10 7 20 30 40 60 50 80 100
[0] [1] [2] [3] [4] [5] [6] [7] [8]

.
.
.

7 10 20 30 40 50 60 80 100
@ 2016 Zanamwe N
[0] [1] [2] [3] [4] [5] [6] [7] [8]
Quicksort Analysis
• Assume that keys are random, uniformly
distributed.
• Best case running time: O(n log2n)
• Worst case running time?
– Recursion:
1. Partition splits array in two sub-arrays:
• one sub-array of size 0
• the other sub-array of size n-1
2. Quicksort each sub-array
– Depth of recursion tree? O(n)
– Number of accesses per partition? O(n)
@ 2016 Zanamwe N
Quicksort Analysis
• Assume that keys are random, uniformly
distributed.
• Best case running time: O(n log2n)
• Worst case running time: O(n2)!!!

@ 2016 Zanamwe N
Quick Sort
def quick_sort(collection):
if len(collection) < 2 :
return collection
pivot = collection[0]
collection.pop(0)
lo = [x for x in collection if x <= pivot]
hi = [x for x in collection if x > pivot]
return quick_sort(lo) + [pivot] + quick_sort(hi)
l = [4, 67, 4,90, 6, 23, 67, 23, 78, 45, 12,1, 55, 88, 99, 239]
l=quick_sort(l)
print(l)

@ 2016 Zanamwe N
Tutorial Question
• Change the pivot so that it is set to:
– the last element
– the median

@ 2016 Zanamwe N

You might also like