-
QuicksortAlgoDS/Algorithm 2020. 1. 16. 22:58
1. Overview
Like Merge Sort, QuickSort is a Divide and Conquer algorithm. It picks an element as pivot and partitions the given array around the picked pivot. There are many different versions of quickSort that pick pivot in different ways.
- Always pick the first element as a pivot.
- Always pick the last element as the pivot (implemented below)
- Pick a random element as pivot.
- Pick the median as a pivot.
2. Description
2.1 Procedure
/* low --> Starting index, high --> Ending index */ quickSort(arr[], low, high) { if (low < high) { /* pi is partitioning index, arr[pi] is now at right place */ pi = partition(arr, low, high); quickSort(arr, low, pi - 1); // Before pi quickSort(arr, pi + 1, high); // After pi } }
/* This function takes last element as pivot, places the pivot element at its correct position in sorted array, and places all smaller (smaller than pivot) to left of pivot and all greater elements to right of pivot */ partition (arr[], low, high) { // pivot (Element to be placed at right position) pivot = arr[high]; i = (low - 1) // Index of smaller element for (j = low; j <= high- 1; j++) { // If current element is smaller than the pivot if (arr[j] < pivot) { i++; // increment index of smaller element swap arr[i] and arr[j] } } swap arr[i + 1] and arr[high]) return (i + 1) }
2.1.1 Illustration of partition():
arr[] = {10, 80, 30, 90, 40, 50, 70} Indexes: 0 1 2 3 4 5 6 low = 0, high = 6, pivot = arr[h] = 70 Initialize index of smaller element, i = -1 Traverse elements from j = low to high-1 j = 0 : Since arr[j] <= pivot, do i++ and swap(arr[i], arr[j]) i = 0 arr[] = {10, 80, 30, 90, 40, 50, 70} // No change as i and j // are same j = 1 : Since arr[j] > pivot, do nothing // No change in i and arr[] j = 2 : Since arr[j] <= pivot, do i++ and swap(arr[i], arr[j]) i = 1 arr[] = {10, 30, 80, 90, 40, 50, 70} // We swap 80 and 30 j = 3 : Since arr[j] > pivot, do nothing // No change in i and arr[] j = 4 : Since arr[j] <= pivot, do i++ and swap(arr[i], arr[j]) i = 2 arr[] = {10, 30, 40, 90, 80, 50, 70} // 80 and 40 Swapped j = 5 : Since arr[j] <= pivot, do i++ and swap arr[i] with arr[j] i = 3 arr[] = {10, 30, 40, 50, 80, 90, 70} // 90 and 50 Swapped We come out of loop because j is now equal to high-1. Finally we place pivot at correct position by swapping arr[i+1] and arr[high] (or pivot) arr[] = {10, 30, 40, 50, 70, 90, 80} // 80 and 70 Swapped Now 70 is at its correct place. All elements smaller than 70 are before it and all elements greater than 70 are after it.
2.1.2 Implementation
# Python program for implementation of Quicksort Sort # This function takes last element as pivot, places # the pivot element at its correct position in sorted # array, and places all smaller (smaller than pivot) # to left of pivot and all greater elements to right # of pivot def partition(arr,low,high): i = ( low-1 ) # index of smaller element pivot = arr[high] # pivot for j in range(low , high): # If current element is smaller than the pivot if arr[j] < pivot: # increment index of smaller element i = i+1 arr[i],arr[j] = arr[j],arr[i] arr[i+1],arr[high] = arr[high],arr[i+1] return ( i+1 ) # The main function that implements QuickSort # arr[] --> Array to be sorted, # low --> Starting index, # high --> Ending index # Function to do Quick sort def quickSort(arr,low,high): if low < high: # pi is partitioning index, arr[p] is now # at right place pi = partition(arr,low,high) # Separately sort elements before # partition and after partition quickSort(arr, low, pi-1) quickSort(arr, pi+1, high) # Driver code to test above arr = [10, 7, 8, 9, 1, 5] n = len(arr) quickSort(arr,0,n-1) print ("Sorted array is:") for i in range(n): print ("%d" %arr[i]), # This code is contributed by Mohit Kumra
Other implementations using Linked list
- Singly Linked List
- Doubly Linked List
2.2 Time Complexity
Particular Worst Worst-case performance O($n^{2}$) Best-case performance O(n log n) 3-Way quicksort Best-case performance O(n) Average performance O(n log n) Worst-case space complexity O(n) Worst-case space complexity (Sedgewick 1978) O(log n) 2.2.1 Analysis of complexity
T(n) = T(k) + T(n-k-1) + O(n)
This notation can be solved using Mater Theorem.
- Worst Case
T(n) = T(0) + T(n-1) + O(n) which is equivalent to # O(n^2) T(n) = T(n-1) + O(n)
- Best Case
# O(N log N) T(n) = 2T(n/2) + O(n)
- Average Case
# O(N log N) T(n) = T(n/9) + T(9n/10) + O(n)
2.3 3-Way Quicksort
In 3 Way QuickSort, an array arr[l..r] is divided into 3 parts:
- a) arr[l..i] elements less than pivot.
- b) arr[i+1..j-1] elements equal to pivot.
- c) arr[j..r] elements greater than pivot.
3. Reference
https://en.wikipedia.org/wiki/Quicksort
https://www.geeksforgeeks.org/quick-sort/
https://www.youtube.com/watch?v=PgBzjlCcFvc&feature=emb_title
https://en.wikipedia.org/wiki/Master_theorem
https://www.geeksforgeeks.org/3-way-quicksort-dutch-national-flag/
https://www.geeksforgeeks.org/quicksort-on-singly-linked-list/
https://www.geeksforgeeks.org/quicksort-for-linked-list/
https://www.geeksforgeeks.org/quicksort-tail-call-optimization-reducing-worst-case-space-log-n/
https://www.geeksforgeeks.org/analysis-of-algorithms-set-2-asymptotic-analysis/
'AlgoDS > Algorithm' 카테고리의 다른 글
Bubble sort (0) 2020.01.17 Heap Sort (0) 2020.01.16 Binary Search (0) 2020.01.16 Recursion (0) 2020.01.16 Searching and Sorting with Array (0) 2019.09.04