I have implemented a merge sort and, as well as sorting, I would like it to compute the number of inversions in the original array.
Below is my attempt at implementing it, which for some reason doesn't compute the number of inversions correctly.
For example, mergeSort([4, 3, 2, 1])
should return (6, [1, 2, 3, 4])
.
def mergeSort(alist):
count = 0
if len(alist)>1:
mid = len(alist)//2
lefthalf = alist[:mid]
righthalf = alist[mid:]
mergeSort(lefthalf)
mergeSort(righthalf)
i=0
j=0
k=0
while i < len(lefthalf) and j < len(righthalf):
if lefthalf[i] < righthalf[j]:
alist[k]=lefthalf[i]
i=i+1
else:
alist[k]=righthalf[j]
count +=len(lefthalf[i:])
j=j+1
k=k+1
while i < len(lefthalf):
alist[k]=lefthalf[i]
i=i+1
k=k+1
while j < len(righthalf):
alist[k]=righthalf[j]
j=j+1
k=k+1
return count, alist
The main problem was not including the counts of sorting left and right sides.
def mergeSort(alist):
count = 0
leftcount = 0
rightcount = 0
blist = []
if len(alist) > 1:
mid = len(alist) // 2
lefthalf = alist[:mid]
righthalf = alist[mid:]
leftcount, lefthalf = mergeSort(lefthalf)
rightcount, righthalf = mergeSort(righthalf)
i = 0
j = 0
while i < len(lefthalf) and j < len(righthalf):
if lefthalf[i] < righthalf[j]:
blist.append(lefthalf[i])
i += 1
else:
blist.append(righthalf[j])
j += 1
count += len(lefthalf[i:])
while i < len(lefthalf):
blist.append(lefthalf[i])
i += 1
while j < len(righthalf):
blist.append(righthalf[j])
j += 1
else:
blist = alist[:]
return count + leftcount + rightcount, blist