So far, we've looked at sorts that take O(n2) time. Those were:
- Insertion Sort
- Bubble Sort
Both of the algorithms are helpful for learning how sorting works, but aren't actually used because they are too slow.
In this lesson, we will look a recursive sorting algorithm and understand why it is faster.
Here's how it works:
- If the array has only one element, return it.
- Find the middle element of the array and name it pivot.
- Move all the elements smaller than the pivot into an array called less.
- Move all the elements equal to the pivot into an array called equal.
- Move all the elements greater than the pivot into an array called greater
- Return the following:
This function passing in less as input + equal + this function passing in greater as input.
Let's go through some examples:
var arr1 = [8,4,2]
- Skip this step as arr1 has 3 elements.
- pivot = 4
- less = [2]
- equal = [4]
- greater = [8]
- return quicksort([2]) + [4] + quicksort([8])
quicksort([2]) and quicksort([4]) hit the basecase in step one and return the input. Therefore, the function returns [2,4,8]
var arr2 = [11,8,15,10,4,14,2]
- Skip this step as arr2 has 7 elements.
- pivot = 10
- less = [8,4,2]
- equal = [10]
- greater = [10,15,14]
- return quicksort([8,4,2]) + [10] + quicksort([11,15,14])
quicksort([8,4,2]) = [2,4,8] as we saw in example one
- Skip this step as the array has 3 elements
- pivot = 15
- less = [11,14]
- equal = [15]
- greater = []
- return quicksort([11,14]) + [15] + []
- Skip this step as the array has 2 elements
- pivot = 11
- less = []
- equal = [11]
- greater = [14]
- return [] + [11] + [14] = [10,14]
Therefore, quicksort([11,15,14]) = [11,14,15]
And so quicksort([8,4,2]) + [10] + quicksort([11,15,14]) = [2,4,8,10,11,14,15]
func quickSort(arr: [Int]) -> [Int] {
guard arr.count > 1 else {return arr} //base case
let pivot = arr[arr.count / 2]
var lessThanPivot = [Int]()
var equalToPivot = [Int]()
var greaterThanPivot = [Int]()
for element in arr {
if element < pivot {
lessThanPivot.append(element)
} else if element > pivot {
greaterThanPivot.append(element)
} else {
equalToPivot.append(element)
}
}
print("\(arr) with pivot: \(pivot)")
print("sort(\(lessThanPivot)) + \(equalToPivot) + sort(\(greaterThanPivot))")
print()
return quickSort(arr: lessThanPivot) + equalToPivot + quickSort(arr: greaterThanPivot) //recurive call
}