|
| 1 | +def dual_pivot_quicksort(arr, low, high): |
| 2 | + """ |
| 3 | + Performs Dual-Pivot QuickSort on the input array. |
| 4 | +
|
| 5 | + Dual-Pivot QuickSort is an optimized version of QuickSort that uses |
| 6 | + two pivot elements to partition the array into three segments in each |
| 7 | + recursive call. This improves performance by reducing the number of |
| 8 | + recursive calls, making it faster on average than the single-pivot |
| 9 | + QuickSort. |
| 10 | +
|
| 11 | + Parameters: |
| 12 | + arr (list): The list to be sorted. |
| 13 | + low (int): The starting index of the segment to sort. |
| 14 | + high (int): The ending index of the segment to sort. |
| 15 | +
|
| 16 | + Returns: |
| 17 | + None: Sorts the array in place. |
| 18 | + """ |
| 19 | + if low < high: |
| 20 | + # Partition the array and get the two pivot indices |
| 21 | + lp, rp = partition(arr, low, high) |
| 22 | + # Recursively sort elements less than pivot1 |
| 23 | + dual_pivot_quicksort(arr, low, lp - 1) |
| 24 | + # Recursively sort elements between pivot1 and pivot2 |
| 25 | + dual_pivot_quicksort(arr, lp + 1, rp - 1) |
| 26 | + # Recursively sort elements greater than pivot2 |
| 27 | + dual_pivot_quicksort(arr, rp + 1, high) |
| 28 | + |
| 29 | +def partition(arr, low, high): |
| 30 | + """ |
| 31 | + Partitions the array segment defined by low and high using two pivots. |
| 32 | +
|
| 33 | + This function arranges elements into three sections: |
| 34 | + - Elements less than pivot1 |
| 35 | + - Elements between pivot1 and pivot2 |
| 36 | + - Elements greater than pivot2 |
| 37 | +
|
| 38 | + Parameters: |
| 39 | + arr (list): The list to partition. |
| 40 | + low (int): The starting index of the segment to partition. |
| 41 | + high (int): The ending index of the segment to partition. |
| 42 | +
|
| 43 | + Returns: |
| 44 | + tuple: Indices of the two pivots in sorted positions (lp, rp). |
| 45 | + """ |
| 46 | + # Ensure the left pivot is less than or equal to the right pivot |
| 47 | + if arr[low] > arr[high]: |
| 48 | + arr[low], arr[high] = arr[high], arr[low] |
| 49 | + pivot1 = arr[low] # left pivot |
| 50 | + pivot2 = arr[high] # right pivot |
| 51 | + |
| 52 | + # Initialize pointers |
| 53 | + i = low + 1 # Pointer to traverse the array |
| 54 | + lt = low + 1 # Boundary for elements less than pivot1 |
| 55 | + gt = high - 1 # Boundary for elements greater than pivot2 |
| 56 | + |
| 57 | + # Traverse and partition the array based on the two pivots |
| 58 | + while i <= gt: |
| 59 | + if arr[i] < pivot1: |
| 60 | + arr[i], arr[lt] = arr[lt], arr[i] # Swap to move smaller elements to the left |
| 61 | + lt += 1 |
| 62 | + elif arr[i] > pivot2: |
| 63 | + arr[i], arr[gt] = arr[gt], arr[i] # Swap to move larger elements to the right |
| 64 | + gt -= 1 |
| 65 | + i -= 1 # Decrement i to re-evaluate the swapped element |
| 66 | + i += 1 |
| 67 | + |
| 68 | + # Place the pivots in their correct sorted positions |
| 69 | + lt -= 1 |
| 70 | + gt += 1 |
| 71 | + arr[low], arr[lt] = arr[lt], arr[low] # Place pivot1 at its correct position |
| 72 | + arr[high], arr[gt] = arr[gt], arr[high] # Place pivot2 at its correct position |
| 73 | + |
| 74 | + return lt, gt # Return the indices of the two pivots |
| 75 | + |
| 76 | +# Example usage |
| 77 | +# Sample Test Case |
| 78 | +arr = [24, 8, 42, 75, 29, 77, 38, 57] |
| 79 | +dual_pivot_quicksort(arr, 0, len(arr) - 1) |
| 80 | +print("Sorted array:", arr) |
0 commit comments