Skip to content

Commit 4924445

Browse files
authored
Add Count Inversions algorithm using Merge Sort
1 parent 0a3a965 commit 4924445

1 file changed

Lines changed: 56 additions & 0 deletions

File tree

sorts/count_inversion.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"""
2+
Count Inversions in an array using a modified Merge Sort algorithm.
3+
4+
An inversion is a pair of indices (i, j) such that:
5+
- i < j
6+
- arr[i] > arr[j]
7+
This represents a disorder in the array relative to a sorted order.
8+
9+
This implementation efficiently counts the number of such inversions
10+
in O(n log n) time by modifying the merge step of Merge Sort.
11+
12+
Use Cases:
13+
----------
14+
- Measuring how far a sequence is from being sorted.
15+
- Evaluating disorder in datasets (e.g., in rankings or sequences).
16+
- Useful in computer vision, bioinformatics, and comparison of lists.
17+
- Core concept in Kendall tau distance and other similarity metrics.
18+
"""
19+
def count_inversions(arr):
20+
def merge_sort(arr):
21+
if len(arr) <= 1:
22+
return arr, 0
23+
24+
mid = len(arr) // 2
25+
left, inv_left = merge_sort(arr[:mid])
26+
right, inv_right = merge_sort(arr[mid:])
27+
merged, inv_split = merge(left, right)
28+
29+
total_inversions = inv_left + inv_right + inv_split
30+
return merged, total_inversions
31+
32+
def merge(left, right):
33+
i = j = inv_count = 0
34+
merged = []
35+
36+
while i < len(left) and j < len(right):
37+
if left[i] <= right[j]:
38+
merged.append(left[i])
39+
i += 1
40+
else:
41+
merged.append(right[j])
42+
j += 1
43+
inv_count += len(left) - i # All remaining in left > right[j]
44+
45+
merged += left[i:]
46+
merged += right[j:]
47+
return merged, inv_count
48+
49+
_, total_inversions = merge_sort(arr)
50+
return total_inversions
51+
52+
53+
# Example usage
54+
if __name__ == "__main__":
55+
sample = [2, 4, 1, 3, 5]
56+
print(f"Inversion count: {count_inversions(sample)}")

0 commit comments

Comments
 (0)