0% found this document useful (0 votes)
2 views124 pages

Quick Sort

Quicksort is a recursive sorting algorithm that uses a divide and conquer strategy by selecting a pivot and partitioning the array into two groups based on the pivot. The algorithm has a best-case and average-case time complexity of O(n log n), while poor pivot choices can lead to O(n^2) performance. The process involves recursively sorting the partitions until the entire array is sorted.

Uploaded by

Anshuman Bindal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views124 pages

Quick Sort

Quicksort is a recursive sorting algorithm that uses a divide and conquer strategy by selecting a pivot and partitioning the array into two groups based on the pivot. The algorithm has a best-case and average-case time complexity of O(n log n), while poor pivot choices can lead to O(n^2) performance. The process involves recursively sorting the partitions until the entire array is sorted.

Uploaded by

Anshuman Bindal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 124

Quicksort

Quicksort

The basic quicksort algorithm is recursive (Follows Divide and
Conquer strategy)
» Chosing the pivot
» Deciding how to partition
» Dealing with duplicates

Wrong decisions give quadratic (n2) run times

Good decisions give n log n run time
The Quicksort Algorithm

The basic algorithm Quicksort(S) has 4 steps
✔ If the number of elements in S is 0 or 1, return
✔ Pick any element P in S. It is called the pivot.
✔Partition S – {P} (the remaining elements in S) into two disjoint groups: Split the
array into two parts – one with elements larger than the
pivot and the other with elements smaller than the pivot.
✔ L = {x Î S – {P}|x < P}
✔ R = {x Î S – {P}|x >= P}
✔Recursively repeat the algorithm for both halves of the original
array: Return the results of Quicksort(L) followed by P followed by Quicksort(R)
Quicksort

● Divide step:
–Pick any element (pivot) P in S P
–Partition S – {P} into two disjoint groups
S1 = {x Î S – {P} | x < P}
S
S2 = {x Î S – {P} | x ³ P}

● Conquer step: recursively sort S1 and S2

● Combine step: the sorted S1 (by the time returned from recursion),
followed by P, followed by the sorted S2 (i.e., nothing extra needs to P
be done) S2

S1

To simplify, we may assume that we don’t have repetitive elements,


So to ignore the ‘equality’ case!
Quicksort
Quicksort
Pivots

Any element can be used as the pivot

The pivot divides the array elements into two groups
» elements smaller than the pivot
» elements larger than the pivot

Some choice of pivots are better than others

The best choice of pivots equally divides the array

Elements equal to the pivot can go in either group
Example
85 24 63 45 17 31 96 50
Example
85 24 63 45 17 31 96 50
Example
85 24 63 45 17 31 96 50

24 45 17 31 50 85 63 96
Example
85 24 63 45 17 31 96 50

24 45 17 31 50 85 63 96

24 45 17 31 85 63 96
Example
85 24 63 45 17 31 96 50

24 45 17 31 50 85 63 96

24 45 17 31 85 63 96
Example
85 24 63 45 17 31 96 50

24 45 17 31 50 85 63 96

24 45 17 31 85 63 96

24 17 31 45
Example
85 24 63 45 17 31 96 50

24 45 17 31 50 85 63 96

24 45 17 31 85 63 96

24 17 31 45

24 17 45
Example
85 24 63 45 17 31 96 50

24 45 17 31 50 85 63 96

24 45 17 31 85 63 96

24 17 31 45

24 17 45
Example
85 24 63 45 17 31 96 50

24 45 17 31 50 85 63 96

24 45 17 31 85 63 96

24 17 31 45

17 24 45
Example
85 24 63 45 17 31 96 50

24 45 17 31 50 85 63 96

24 45 17 31 85 63 96

24 17 31 45

17 24 45

24
Example
85 24 63 45 17 31 96 50

24 45 17 31 50 85 63 96

24 45 17 31 85 63 96

24 17 31 45

17 24 45
Example
85 24 63 45 17 31 96 50

24 45 17 31 50 85 63 96

24 45 17 31 85 63 96

17 24 31 45

45
Example
85 24 63 45 17 31 96 50

24 45 17 31 50 85 63 96

24 45 17 31 85 63 96

17 24 31 45
Example
85 24 63 45 17 31 96 50

24 45 17 31 50 85 63 96

17 24 31 45 85 63 96
Example
85 24 63 45 17 31 96 50

17 24 31 45 50 85 63 96

85 63 96
Example
85 24 63 45 17 31 96 50

17 24 31 45 50 85 63 96

85 63 96
Example
85 24 63 45 17 31 96 50

17 24 31 45 50 85 63 96

85 63 96
Example
85 24 63 45 17 31 96 50

17 24 31 45 50 85 63 96

85 63 96

85 63
Example
85 24 63 45 17 31 96 50

17 24 31 45 50 85 63 96

85 63 96

85 63
Example
85 24 63 45 17 31 96 50

17 24 31 45 50 85 63 96

85 63 96

63 85
Example
85 24 63 45 17 31 96 50

17 24 31 45 50 85 63 96

85 63 96

63 85
Example
85 24 63 45 17 31 96 50

17 24 31 45 50 85 63 96

63 85 96
Example
85 24 63 45 17 31 96 50

17 24 31 45 50 63 85 96
Example
17 24 31 45 50 63 85 96
Algorithm

Now let us look the following:
–Algorithm
–Analysis
–Impact of choosing the pivot on runtime of the algorithm
Quicksort - Pseudocode
quickSort(int array[], int low, int high)
{
if (low >= high)
{
return //Base Case, we’re done
}
else
{
//partition array around pivot value array[low]
//partition_Index contains the new location of pivot value

partition_Index=partition(array, low, high)


//quickSort array before partition_Index
quickSort(array,low,partition_Index-1)
//quickSort array after partition_Index
quickSort(array,partition_Index+1,high)
}
}
partition(int array[], int low, int high)
{
int LEFT=low, RIGHT=high, pivot=array[low];
while (LEFT<RIGHT) //out of loop when RIGHT and LEFT cross
{
/*scan from left to right using index called LEFT
stop when locate an element that should be right of pivot*/
while(array[LEFT] < pivot && LEFT<=high) {LEFT++;}

/*scan from right to left using index called RIGHT


STOP when locate an element that should be left of pivot*/
while(array[RIGHT] > pivot && RIGHT>=low ) {RIGHT--;}

if(LEFT<RIGHT)
swap(array[LEFT],array[RIGHT])
}
// swap pivot and the element at the array location where LEFT/RIGHT cross
array[low]=array[RIGHT];
array[RIGHT]=pivot;
//return the location where LEFT/RIGHT cross
return RIGHT;
}
Trace of the Quicksort
Algorithm
0 1 2 3 4 5

quickSort(arr,0,5) 6 5 9 12 3 4
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 9 12 3 4
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 9 12 3 4
pivot= ?

Partition Initialization...
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 9 12 3 4
pivot=6

Partition Initialization...
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 9 12 3 4
pivot=6
left

Partition Initialization...
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 9 12 3 4
pivot=6
left right

Partition Initialization...
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 9 12 3 4
pivot=6
left right

right moves to the left until


value that should be to left
of pivot...
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 9 12 3 4
pivot=6
left right
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 9 12 3 4
pivot=6
left right

left moves to the right until


value that should be to right
of pivot...
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 9 12 3 4
pivot=6
left right
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 9 12 3 4
pivot=6
left right
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 9 12 3 4
pivot=6
left right

swap arr[left] and arr[right]


quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 4 12 3 9
pivot=6
left right

repeat right/left scan


UNTIL left & right cross
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 4 12 3 9
pivot=6
left right

right moves to the left until


value that should be to left
of pivot...
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 4 12 3 9
pivot=6
left right
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 4 12 3 9
pivot=6
left right

left moves to the right until


value that should be to right
of pivot...
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 4 12 3 9
pivot=6
left right
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 4 12 3 9
pivot=6
left right

swap arr[left] and arr[right]


quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 4 3 12 9
pivot=6
left right

swap arr[left] and arr[right]


quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 4 3 12 9
pivot=6
left right

repeat right/left scan


UNTIL left & right cross
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 4 3 12 9
pivot=6
left right

right moves to the left until


value that should be to left
of pivot...
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 4 3 12 9
pivot=6
left

right
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 4 3 12 9
pivot=6
left

right

right & left CROSS!!!


quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 6 5 4 3 12 9
pivot=6
left

right

right & left CROSS!!!


1 - Swap pivot and arr[right]
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 3 5 4 6 12 9
pivot=6
left

right

right & left CROSS!!!


1 - Swap pivot and arr[right]
quickSort(arr,0,5)

0 1 2 3 4 5

partition(arr,0,5) 3 5 4 6 12 9
pivot=6
left

right

right & left CROSS!!!


1 - Swap pivot and arr[right]
2 - Return new location of pivot to caller

return 3
0 1 2 3 4 5

quickSort(arr,0,5) 3 5 4 6 12 9

pivot
position

Recursive calls to quickSort()


using partitioned array...
quickSort(arr,0,5)
0 1 2 3 4 5

3 5 4 6 12 9
quickSort(arr,0,2) quickSort(arr,4,5)

0 1 2 4 5

3 5 4 12 9
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)

0 1 2 4 5

3 5 4 12 9
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)

0 1 2 4 5

3 5 4 12 9

Partition Initialization...
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)

0 1 2 4 5

3 5 4 12 9

Partition Initialization...
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)

0 1 2 4 5

3 5 4 12 9

left

Partition Initialization...
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)

0 1 2 4 5

3 5 4 12 9

left right

Partition Initialization...
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)

0 1 2 4 5

3 5 4 12 9

left right

right moves to the left until


value that should be to left
of pivot...
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)

0 1 2 4 5

3 5 4 12 9

left right
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)

0 1 2 4 5

3 5 4 12 9

left

right
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)

0 1 2 4 5

3 5 4 12 9

left

right

right & left CROSS!!!


quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)

0 1 2 4 5

3 5 4 12 9

left

right

right & left CROSS!!!


1 - Swap pivot and arr[right]
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)

0 1 2 4 5

3 5 4 12 9

left

right

right & left CROSS!!!


1 - Swap pivot and arr[right]
2 - Return new location of pivot to caller

return 0
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

0 1 2 4 5

3 5 4 12 9

Recursive calls to quickSort()


using partitioned array...
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)

0 1 2 12 9
3 5 4
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)

0 1 2 12 9
3 5 4

Base case triggered...


halting recursion.
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)

0 1 2 12 9
3 5 4

Base Case: Return


quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4

Partition Initialization...
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4

Partition Initialization...
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4
left

Partition Initialization...
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4
left right

right moves to the left until


value that should be to left
of pivot...
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4
left right
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4
left right

left moves to the right until


value that should be to right
of pivot...
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4

right

left
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4

right

left

right & left CROSS!


quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4

right

left

right & left CROSS!


1- swap pivot and arr[right]
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 4 5

right

left

right & left CROSS!


1- swap pivot and arr[right]
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 4 5

right

left

right & left CROSS!


1- swap pivot and arr[right]
2 – return new position of pivot
return 2
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)

0 12 9
3
quickSort(arr,1,1)

4
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)

0 12 9
3
quickSort(arr,1,1)

4
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)

0 12 9
3
quickSort(arr,1,1)

4
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,4,5)

quickSort(arr,0,0) 4 5
quickSort(arr,1,2)

0 9 12
3
quickSort(arr,1,1)

4
quickSort(arr,0,5)

quickSort(arr,0,2) quickSort(arr,4,5)

quickSort(arr,0,0) quickSort(arr,1,2) quickSort(arr,4,5)

3
quickSort(arr,1,1)

1 quickSort(arr,4,4)
4
4
9
Analysis

Running time
–pivot selection: constant time, i.e. O(1)
–partitioning: linear time, i.e. O(N)
–running time of the two recursive calls


T(N)=T(i)+T(N-i-1)+cN where c is a constant
–i: number of elements in partition S1 and N-i-1 is the remaining
elements in partition S2
–cN is the time required for partitioning at each level of the recursive
call.

BASE CASE: T(n)=c, for n=1
Analysis – Worst case

When will the worst case happen?
–The pivot is the smallest element every time
–The Partition is always unbalanced
Example – Worst case
Example – Worst case
17 24 31 45 50 63 85 96
Example – Worst case
17 24 31 45 50 63 85 96
Example – Worst case
17 24 31 45 50 63 85 96

17 24 31 45 50 63 85 96
Example – Worst case
17 24 31 45 50 63 85 96

17 24 31 45 50 63 85 96

17 24 31 45 50 63 85
Example – Worst case
17 24 31 45 50 63 85 96

17 24 31 45 50 63 85 96

17 24 31 45 50 63 85
Example – Worst case
17 24 31 45 50 63 85 96

17 24 31 45 50 63 85 96

17 24 31 45 50 63 85
Example – Worst case
17 24 31 45 50 63 85 96

17 24 31 45 50 63 85 96

17 24 31 45 50 63 85

17 24 31 45 50 63

How high will this tree call stack get?


Worst Case
• T(n) = T(n-1) + n

For the comparisons


For the recursive call in the partitioning
Analysis – Worst case

When will the worst case happen?
–The pivot is the smallest element every time
–The Partition is always unbalanced
–Considering the recurrence relation:
T(N)=T(i)+T(N-i-1)+cN

Substitute i=0 for the worst case, because one of the partitions always contains no
element because the smallest element is pivot itself.

T(N)=T(N-1)+cN

We have already seen this kind of recurrence and solved using
iterative based method to get O(N2) running time.
Analysis – Best case

When will the Best case happen?
–Pivot is the middle element every time and splits
the array in halves
–The Partition is always balanced
Example – Best case

15 7 9 3 13 5 11 2 14 6 10 1 12 4 8
Example – Best case

7 3 6 2 5 1 4 8 15 9 13 11 14 10 12
Example – Best case

7 3 6 1 5 2 4 8 15 9 13 11 14 10 12

7 3 6 1 5 2 4 15 9 13 11 14 10 12
Example – Best case

7 3 6 1 5 2 4 8 15 9 13 11 14 10 12

7 3 6 1 5 2 4 15 9 13 11 14 10 12
Example – Best case

7 3 5 1 6 2 4 8 15 9 13 11 14 10 12

3 1 2 4 7 5 6 9 11 10 12 15 13 14
Example – Best case

7 3 5 1 6 2 4 8 15 9 13 11 14 10 12

3 1 2 4 7 5 6 9 11 10 12 15 13 14

3 1 2 7 5 6 9 11 10 15 13 14
Example – Best case

7 3 5 1 6 2 4 8 15 9 13 11 14 10 12

3 1 2 4 7 5 6 99 11
11 10
10 12
12 15
15 13
13 14
14

3 1 2 7 5 6 9 11 10 15 13 14
Example – Best case

7 3 5 1 6 2 4 8 15 9 13 11 14 10 12

3 1 2 4 7 5 6 9 11 10 12 15 13 14

1 2 3 5 6 7 9 10 11 13 14 15
What is size at each level?

n 7 3 5 1 6 2 4 8 15 9 13 11 14 10 12

n-1 3 1 2 4 7 5 6 9 11 10 12 15 13 14

n-3 1 2 3 5 6 7 9 10 11 13 14 15

n-7 1 3 5 7 9 11 13 15
Best Case, more precisely
• S0(n) = n
• S1(n) = n - 1
• S2(n) = (n – 1) – 2 = n – (1 + 2) = n-3
• S3(n) = ((n – 1) – 2) - 4 = n – (1 + 2 + 4) = n-7
• …
• Si(n) = n – ( 1 + 2 + 22+ … + 2i-1) = n - 2i + 1

• Height is O(log n)
• No more than n work is done at any one level
• Best case time complexity is O(n log n)
Analysis – Best case

When will the Best case happen?
–Pivot is the middle element every time and splits the
array in halves
–The Partition is always balanced
–Considering the recurrence relation:
T(N)=T(i)+T(N-i-1)+cN

Substitute i=N/2 for the best case, because one of the
partitions always contains almost halve of the elements.

T(N)=T(N/2)+T(N/2-1)+cN

T(N)≈2T(N/2)+cN

We have already seen this recurrence for the Merge
Sort which has O(Nlog2N) running time.
Analysis – Average case

In the average, we do not know where the split
happens.
–We take all possible values of split locations, add
all their complexities and divide with N to get the
average case complexity.

The cost to quicksort N items equals N units for the
partitioning plus the cost of the two recursive calls

The average cost of each recursive call equals the
average over all possible sub-problem sizes
Average cost of the recursive calls
Recurrence Relation
……
Nth Harmonic no is O(log N)
Thank you

You might also like