key idea: partition array around a pivot element
--pick element of array
--arrange array so that:
left of pivot ->less than pivot
right of pivot -> greater than pivot
2 cool facts about partition:
linear O(n) time, no extra memory
reduces problem size
The Running time depends on the quality of the Pivot
worst case: always select the first element as pivot ----Theta(n^2)
best case: every recursive call chooses the median element of its subarray as its pivot ---- Theta(nlogn)
Random Pivots: average running time of Quicksort is O(nlogn)
Pseudocode for QuickSort:
QuickSort(array A, length n)
if n = 1 return
p = choosePivot(A, n)
Partition A around P
recursively Sort 1st part
recursively Sort 2nd part
Pseudocode for Partition:
Partition(A, l, r)
P = A[l]
i = l+1
for j = l+1 to r
if A[j] < p
swap(A[j], A[i])
i = i+1
swap(A[l], A[i-1])
Python code:
def choosePivot(number, l, r): #choose the first element as the Pivot
p = l
return p
def partition(number, l, r, p):
number[l], number[p] = number[p], number[l] #swap the lth number and the pth number which means move the Pivot to the head of
i = l + 1 #the number list in order to make the comparison easier.
for j in range(l+1, r): #if the jth number is smaller than Pivot, swap
if number[j] < number[l]:
number[j], number[i] = number[i], number[j]
i = i+1 #move the Pivot pointer to the next
number[l], number[i-1] = number[i-1], number[l] #move the Pivot to the right position
new_p = i-1
return new_p
def quickSort(number, l, r):
length = len(number[l:r])
if length > 1:
p = choosePivot(number, l, r)
new_p = partition(number, l, r, p)
quickSort(number, l, new_p)
quickSort(number, new_p+1, r)
if __name__ == '__main__':
f = open('QuickSort.txt')
_number = list(f)
number = []
for n in _number:
number.append(int(n))
quickSort(number, 0, len(number))
print(number)