Lecture 2 Sorting II¶
Recursive Bubble Sort Algorithm¶
Examples:
Example 1:
Input: N = 6, array[] = {13,46,24,52,20,9}
Output: 9,13,20,24,46,52
Explanation: After sorting we get 9,13,20,24,46,52
Example 2:
Input: N = 5, array[] = {5,4,3,2,1}
Output: 1,2,3,4,5
Explanation: After sorting we get 1,2,3,4,5
approach1¶
- main loop iteration
- second loop recursive
In [3]:
def bubble_sort(nums):
n = len(nums)
def sort(j):
if j == n-1:
return
if nums[j] > nums[j+1]:
nums[j],nums[j+1] = nums[j+1],nums[j]
sort(j+1)
for i in range(n):
sort(0)
return nums
print(bubble_sort([13,46,24,52,20,9]))
print(bubble_sort([5,4,3,2,1]))
[9, 13, 20, 24, 46, 52] [1, 2, 3, 4, 5]
Complexity¶
- O(N^2) : N = len(nums)
- O(N) : deppest call stack of size N
Recursive Insertion Sort Algorithm¶
Examples:
Example 1:
Input: N = 6, array[] = {13,46,24,52,20,9}
Output: 9,13,20,24,46,52
Explanation: After sorting we get 9,13,20,24,46,52
Example 2:
Input: N = 5, array[] = {5,4,3,2,1}
Output: 1,2,3,4,5
Explanation: After sorting we get 1,2,3,4,5
Approach 1¶
- convert iteration to recursion
In [ ]:
def insert_sort(nums):
n = len(nums)
def sort(j):
if j <0 or nums[j] < nums[j+1]:
return
nums[j],nums[j+1] = nums[j+1],nums[j]
sort(j-1)
for i in range(1,n):
sort(i-1)
return nums
print(insert_sort([13,46,24,52,20,9]))
print(insert_sort([5,4,3,2,1]))
[9, 13, 20, 24, 46, 52] [1, 2, 3, 4, 5]
Complexity¶
- O(N^2) : N = len(nums)
- O(N) : deppest call stack of size N
Partition The array¶
We are given an array , we need to partition the array such that the elements of the left of nums are smaller and right are greater
Approach 1 (Quick Select)¶
- Assume that parition index is 0
- Using left and right cursors where left = start +1 and right = n
- We will swap left and right when parition conditions fail
- swap right with parition index and return partition
In [5]:
def partition(nums):
def helper(start, end):
partition_idx = start
left = start +1
right = end
while left <= right:
if nums[left]<=nums[partition_idx]:
left+=1
elif nums[right] >= nums[partition_idx]:
right-=1
else:
nums[left],nums[right] = nums[right],nums[left]
nums[partition_idx],nums[right] = nums[right],nums[partition_idx]
return right
n = len(nums)
return helper(0,n-1),nums
print(partition([5,2,4,6,100,49,29,50]))
print(partition([1,6,400,2000,75,9,3,599,88]))
(2, [4, 2, 5, 6, 100, 49, 29, 50]) (0, [1, 6, 400, 2000, 75, 9, 3, 599, 88])
Complexity¶
- O(N) : N = len(nums)
- O(1)
Quick Sort¶
Example 1:
Input: N = 5 , Arr[] = {4,1,7,9,3}
Output: 1 3 4 7 9
Explanation: After sorting the array becomes 1, 3, 4, 7, 9
Example 2:
Input: N = 8 , Arr[] = {4,6,2,5,7,9,1,3}
Output: 1 2 3 4 5 6 7 9
Explanation: After sorting the array becomes 1, 3, 4, 7, 9
Approach 1¶
- Parition the array
- Keep running the partition till the array size is 1
In [13]:
def quick_sort(nums):
n = len(nums)
def partition(start,end):
idx = start
left = start +1
right = end
while left < right:
if nums[left] <= nums[idx]:
left +=1
elif nums[right] >= nums[idx]:
right -=1
else:
nums[left],nums[right] = nums[right],nums[left]
nums[right],nums[idx] = nums[idx],nums[right]
return right
def sort(start,end):
if start >=end:
return
idx = partition(start,end)
sort(start,idx-1)
sort(idx+1,end)
sort(0,n-1)
return nums
print(quick_sort([4,1,7,9,3]))
print(quick_sort([4,6,2,5,7,9,1,3]))
[1, 3, 9, 4, 7] [3, 1, 2, 7, 4, 5, 6, 9]
Complexity¶
- O(N^2) : N= len(nums)
- O(N) : N = len(nums)
Merge Sort Algorithm¶
Input : N=7,arr[]={3,2,8,5,1,4,23}
Output : {1,2,3,4,5,8,23}
Input : N=5, arr[]={4,2,1,6,7}
Output : {1,2,4,6,7}
Approach 1 (Recursive)¶
- Divide and conqur
- Divide the array into smaller array till it reaches 1
- Combining sorted array is the easist
In [6]:
def sort_list(nums):
N = len(nums)
def merge(low,mid,high):
temp = []
left,right = low,mid+1
while left <= mid and right <= high:
if nums[left] <= nums[right]:
temp.append(nums[left])
left +=1
else:
temp.append(nums[right])
right +=1
while left <= mid:
temp.append(nums[left])
left +=1
while right <= high:
temp.append(nums[right])
right +=1
for i in range(low,high +1):
nums[i] = temp[i-low]
def merge_sort(low,high):
if low == high:
return
mid = (low + high) //2
merge_sort(low,mid)
merge_sort(mid+1,high)
merge(low,mid,high)
merge_sort(0,N-1)
return nums
print(sort_list([3,2,8,5,1,4,23]))
print(sort_list([4,2,1,6,7]))
[1, 2, 3, 4, 5, 8, 23] [1, 2, 4, 6, 7]
Complexity¶
- N = len(nums)
- O(N log N)
- O(N)