Lecture 2 Sorting II¶
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
- PS we need to run it left <= right , because even if there only 1 element left
- i.e. both left and right points to single element
- we need to swap that element with the pivot idx later too
In [15]:
def partition(nums):
def swap(i,j):
nums[i],nums[j] = nums[j],nums[i]
n = len(nums)
idx = 0
left = idx+1
right = n-1
while left <= right:
if nums[idx] >= nums[left]:
left +=1
elif nums[idx] <= nums[right]:
right -=1
else:
swap(left,right)
left +=1
right -=1
swap(idx,right)
print(right)
return 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 [21]:
def quick_sort(nums):
n = len(nums)
def swap(i,j):
nums[i],nums[j] = nums[j],nums[i]
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:
swap(left,right)
swap(right,idx)
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, 4, 7, 9] [1, 2, 3, 4, 5, 6, 7, 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, as list with only 1 element is already sorted
- Combining sorted array
- left ptr pointing to start of left sub array
- right ptr pointing to start of right sub array
- we assume both left and right sub array are already sorted
- we need to create a temp array to store the result
- move the left and right ptr appropriatelt
In [ ]:
def sort_list(nums):
N = len(nums)
def merge(low,mid,high):
temp = []
left,right = low,mid+1
## appropriately moveing left and right ptrs till both of them has atleast 1 element
while left <= mid and right <= high:
if nums[left] <= nums[right]:
temp.append(nums[left])
left +=1
else:
temp.append(nums[right])
right +=1
# when all the elements of right are pushed but left has few
while left <= mid:
temp.append(nums[left])
left +=1
# when all the elements of left are pushed but right has few
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):
# when only 1 element left , list if already sorted
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)
Appraoch 2 (More pythonic)¶
In [23]:
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
temp.extend(nums[left:mid+1])
temp.extend(nums[right:high+1])
nums[low:high+1] = temp
def merge_sort(low,high):
# when only 1 element left , list if already sorted
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]