I am trying to use mergesort--which I get--to count the number of split inversions in a list (that is, where an element in the first half of the unsorted list should appear after a given element in the second half of the unsorted list; for example [3 2 1 4] would contain the split inversion (3, 1), but not (3, 2) as 3 and 2 are both in the first half). When I get to the final print statement, I am getting the answer I expect--in this case 9--but the return value is all wonky since it's returning the split value through the recursion. I've tried all sorts of combinations of indexing to no avail. Any help? (using Python 2.7)
(For the record, this is a Coursera homework problem, but I'm just learning for fun--no one's grading this other than me.)
def mergesort(lst):
'''Recursively divides list in halves to be sorted'''
if len(lst) is 1:
return lst
middle = int(len(lst)/2)
left = mergesort(lst[:middle])
right = mergesort(lst[middle:])
sortedlist = merge(left, right)
return sortedlist
def merge(left, right):
'''Subroutine of mergesort to sort split lists. Also returns number
of split inversions (i.e., each occurence of a number from the sorted second
half of the list appearing before a number from the sorted first half)'''
i, j = 0, 0
splits = 0
result = []
while i < len(left) and j < len(right):
if left[i] < right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
splits += len(left[i:])
result += left[i:]
result += right[j:]
print result, splits
return result, splits
print mergesort([7,2,6,4,5,1,3,8])
We can count inversions by grouping them by second element. For example, in the array [4, 3, 1, 2], the element pairs (4, 3), (4, 1), (4, 2), (3, 1), and (3, 2) are inversions.
How many inversions are there in the array arr = {1,5,4,2,3}? Explanation: The necessary condition for an inversion is arr[i]>arr[j] and i<j. So there are 5 inversions in the array.
Modify your mergesort
function to disregard the intermediate splits.
def mergesort(lst):
'''Recursively divides list in halves to be sorted'''
if len(lst) == 1:
return lst, 0
middle = len(lst)/2
left = mergesort(lst[:middle])[0] # Ignore intermediate splits
right = mergesort(lst[middle:])[0] # Ignore intermediate splits
sortedlist, splits = merge(left, right)
return sortedlist, splits
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With