Program to find out the number of shifts required to sort an array using insertion sort in python

Insertion sort moves elements one position at a time to place them in their correct sorted position. Each movement is called a shift. We need to count the total number of shifts required to sort an array using insertion sort.

The key insight is that the number of shifts for each element equals the number of larger elements that appear before it in the array. This is called the inversion count.

Example Walkthrough

Given array [4, 5, 3, 1, 2], let's trace the insertion sort process ?

Step 1: [4, 5, 3, 1, 2] ? 0 shifts (4 stays in place)
Step 2: [4, 5, 3, 1, 2] ? 0 shifts (5 stays in place) 
Step 3: [3, 4, 5, 1, 2] ? 2 shifts (3 moves past 4 and 5)
Step 4: [1, 3, 4, 5, 2] ? 3 shifts (1 moves past 3, 4, and 5)
Step 5: [1, 2, 3, 4, 5] ? 3 shifts (2 moves past 3, 4, and 5)

Total shifts: 0 + 0 + 2 + 3 + 3 = 8

Method 1: Using Binary Indexed Tree (Fenwick Tree)

This approach uses a Binary Indexed Tree to efficiently count inversions ?

def solve(input_arr):
    length = len(input_arr)
    temp_arr = [0] * 1000001
    ans = 0
    
    for item in input_arr:
        # Query: count elements greater than current item
        val = item
        while val > 0:
            ans += temp_arr[val]
            val -= val & -val
        
        # Update: add current item to the tree
        val = item
        while val <= 1000000:
            temp_arr[val] = temp_arr[val] + 1
            val += val & -val
    
    # Total possible inversions - actual inversions = shifts
    ans = length * (length - 1) // 2 - ans
    return ans

# Test the function
print(solve([4, 5, 3, 1, 2]))
8

Method 2: Simple Inversion Count

A more straightforward approach that directly counts inversions ?

def count_shifts_simple(arr):
    shifts = 0
    n = len(arr)
    
    # For each element, count how many larger elements come before it
    for i in range(n):
        for j in range(i):
            if arr[j] > arr[i]:
                shifts += 1
    
    return shifts

# Test with the same array
test_array = [4, 5, 3, 1, 2]
print(f"Array: {test_array}")
print(f"Shifts required: {count_shifts_simple(test_array)}")
Array: [4, 5, 3, 1, 2]
Shifts required: 8

How It Works

The algorithm counts inversions − pairs where a larger element appears before a smaller one. Each inversion represents a shift needed during insertion sort.

For element at position i, we count how many elements at positions 0 to i-1 are greater than arr[i]. This gives us the number of shifts needed for that element.

Comparison

Method Time Complexity Space Complexity Best For
Binary Indexed Tree O(n log max_val) O(max_val) Large arrays with bounded values
Simple Counting O(n²) O(1) Small arrays, educational purposes

Conclusion

The number of shifts in insertion sort equals the inversion count of the array. Use the Binary Indexed Tree approach for efficiency with large datasets, or the simple counting method for better understanding of the concept.

Updated on: 2026-03-26T15:06:37+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements