0% found this document useful (0 votes)
56 views16 pages

Divide and Conquer (Quicksort) : CSE373: Design and Analysis of Algorithms

Quicksort follows the divide and conquer paradigm. It works by partitioning the array around a pivot element, and then recursively sorting the subarrays. The partitioning step separates the array into two subarrays - elements less than or equal to the pivot are placed in one subarray, and elements greater than the pivot are placed in the other. Quicksort then recursively calls itself on the two subarrays. The partitioning is the key step, and impacts the performance - balanced partitions lead to optimal O(n log n) performance on average, while unbalanced partitions can cause worst case O(n^2) behavior.
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)
56 views16 pages

Divide and Conquer (Quicksort) : CSE373: Design and Analysis of Algorithms

Quicksort follows the divide and conquer paradigm. It works by partitioning the array around a pivot element, and then recursively sorting the subarrays. The partitioning step separates the array into two subarrays - elements less than or equal to the pivot are placed in one subarray, and elements greater than the pivot are placed in the other. Quicksort then recursively calls itself on the two subarrays. The partitioning is the key step, and impacts the performance - balanced partitions lead to optimal O(n log n) performance on average, while unbalanced partitions can cause worst case O(n^2) behavior.
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/ 16

Lecture 05

Divide and Conquer (quicksort)


CSE373: Design and Analysis of Algorithms
Quicksort

• Follows the divide-and-conquer paradigm.


• Divide: Partition (separate) the array A[p..r] into two (possibly empty)
subarrays A[p..q–1] and A[q+1..r].
– Each element in A[p..q–1]  A[q].
– A[q]  each element in A[q+1..r].
– Index q is computed as part of the partitioning procedure.
• Conquer: Sort the two subarrays by recursive calls to quicksort.
• Combine: The subarrays are sorted in place – no work is needed to
combine them.
• How do the divide and combine steps of quicksort compare with
those of merge sort?
Pseudocode
PARTITION(A,
PARTITION(A,p,p,r)r)
1.1. xx==A[r]
A[r]
2.2. ii==p-1
p-1
3.3. for
forjj==pptotorr––11
4.4. A[j]  xx
ififA[j]
5.5. ii==ii++11
6.6. exchange
exchangeA[i]
A[i]with
withA[j]
A[j]
7.7. exchange
exchange A[i A[i++1]1]with
withA[r]
A[r] QUICKSORT(A,
QUICKSORT(A,p,p,r)r)
8.8. return
returnii++11 1.1. ififpp<<rrthen
then
A[p..r] 2.2. qq==PARTITION(A,
PARTITION(A,p,p,r);
r);
3.3. QUICKSORT
QUICKSORT(A, (A,p,p,qq––1);
1);
5 4.4. QUICKSORT
QUICKSORT(A, (A,qq++1,1,r)r)
A[p..q – 1] A[q+1..r]
Partition 5

5 5
Example
p r
initially: 2 5 8 3 9 4 1 7 10 6 note: pivot (x) = 6
i j

next iteration: 2 5 8 3 9 4 1 7 10 6
PARTITION(A,
PARTITION(A,p,p,r)r)
i j 1.1. xx==A[r]
A[r]
2.2. i i==p-1
p-1
next iteration: 2 5 8 3 9 4 1 7 10 6 3.3. for
forj j==pptotor r––11
i j 4.4. A[j]  xx
ififA[j]
5.5. i i==i i++11
next iteration: 2 5 8 3 9 4 1 7 10 6 6.6. exchange
exchangeA[i] A[i]with
withA[j]
A[j]
7.7. exchange A[i + 1] with
exchange A[i + 1] with A[r] A[r]
i j 8.8. return
returni i++11
next iteration: 2 5 3 8 9 4 1 7 10 6
i j
Example (Continued)
next iteration: 2 5 3 8 9 4 1 7 10 6
i j
next iteration: 2 5 3 8 9 4 1 7 10 6
i j
next iteration: 2 5 3 4 9 8 1 7 10 6 PARTITION(A,
PARTITION(A,p,p,r)r)
1.1. xx==A[r]
A[r]
i j 2.2. i i==p-1
p-1
3.3. for
forj j==pptotor r––11
next iteration: 2 5 3 4 1 8 9 7 10 6 4.4. A[j]  xx
ififA[j]
i j 5.5. i i==i i++11
6.6. exchange
exchangeA[i] A[i]with
withA[j]
A[j]
next iteration: 2 5 3 4 1 8 9 7 10 6 7.7. exchange A[i + 1] with A[r]
exchange A[i + 1] with A[r]
i j 8.8. return
returni i++11
next iteration: 2 5 3 4 1 8 9 7 10 6
i j
after final swap: 2 5 3 4 1 6 9 7 10 8
i j
Partitioning
• Select the last element A[r] in the subarray A[p..r] as
the pivot – the element around which to partition.
• As the procedure executes, the array is partitioned
into three (possibly empty) regions.
1. A[p..i] — All entries in this region are  pivot.
2. A[i+1..j – 1] — All entries in this region are > pivot.
3. A[r] = pivot.
Complexity of Partition
• PartitionTime(n) is given by the number of
iterations in the for loop.
• (n) : n = r – p + 1.
PARTITION(A,
PARTITION(A,p,p,r)r)
1.1. xx==A[r]
A[r]
2.2. ii==p-1
p-1
3.3. for
forjj==pptotorr––11
4.4. A[j]  xx
ififA[j]
5.5. ii==ii++11
6.6. exchange
exchangeA[i]
A[i]with
withA[j]
A[j]
7.7. exchange
exchange A[i A[i++1]1]with
withA[r]
A[r]
8.8. return
returnii++11
Algorithm Performance
Running time of quicksort depends on whether the
partitioning is balanced or not.

– Best case: occurs when the recursion tree is always


balanced
– Worst case: occurs when the recursion tree is always
unbalanced
– Average case: computed by using expected value of
running time assuming that the pivot elements are randomly
distributed
Best-case Partitioning
• Size of each subproblem  n/2.
– One of the subproblems is of size n/2
– The other is of size n/2 1.
– Called a n/2: (n/2 1) split
• Recurrence for running time
– T(n)  2T(n/2) + PartitionTime(n)
= 2T(n/2) + (n)
• T(n) = (n lg n)
Recursion Tree for Best-case Partition
cn cn

cn/2 cn/2 cn

lg n

cn/4 cn/4 cn/4 cn/4 cn

c c c c c c cn
Total : O(n lg n)
Best-case analysis
Worst-case of quicksort
• Worst-Case Partitioning (Unbalanced Partitions):
– Occurs when every call to partition results in the most unbalanced
partition.
– Partition is most unbalanced when
• Subproblem 1 is of size n – 1, and subproblem 2 is of size 0 or vice versa.
• pivot  every element in A[p..r – 1] or pivot < every element in A[p..r – 1].
– Every call to partition is most unbalanced when
• Array A[1..n] is sorted or reverse sorted!
• One side of partition always has one element.
Randomized quicksort
How can we ENSURE that each element of A are
equally likely to be the pivot?
Randomized quicksort
Standard Problematic Algorithm :
Randomized quicksort

RANDOMIZED-PARTITION (A, p, r)
1 i←RANDOM(p, r)
2 exchange A[r]↔A[i]
3 return PARTITION(A, p, r)

RANDOMIZED-QUICKSORT (A,p,r)
1 if p<r
2 then q←RANDOMIZED-PARTITION (A, p, r)
RANDOMIZED-QUICKSORT (A, p, q-1)
RANDOMIZED-QUICKSORT (A, q+1, r)

Average and worst case running time of Randomized-QuickSort is the same as that
of QuickSort; but in practice Randomized-QuickSort is typically much faster
Quicksort in practice

You might also like