Recursions and While loops in Merge Sort

So I'm trying my best to visualize how this merge sort process would go, but I'm stuck with the recursions and triple While loops, and how do these recursions affect the current divisions of the array [1,9,7,10,11] the first half and [8,3,2,5,6,4] the second half. I can understand the first half of the code but I'm getting lost when trying to follow the flow of these while loops. Thank you so much for your answers!!!

def merge_sort(array):

if len(array) > 1:
    start_mid = array[:len(array)//2]
    mid_end = array[len(array)//2:]

    #recusion process
    merge_sort(start_mid)
    merge_sort(mid_end)


    left_ind = 0
    right_ind = 0
    merged_ind = 0
    while left_ind < len(start_mid) and right_ind < len(mid_end):
        if start_mid[left_ind] < mid_end[right_ind]:
            array[merged_ind] = start_mid[left_ind]
            left_ind += 1
        else:
            array[merged_ind] = mid_end[right_ind]
            right_ind += 1
        merged_ind += 1
    while left_ind < len(start_mid):
        array[merged_ind] = start_mid[left_ind]
        left_ind += 1
        merged_ind += 1
    while right_ind < len(mid_end):
        array[merged_ind] = mid_end[right_ind]
        right_ind += 1
        merged_ind += 1

array_test = [1,9,7,10,11,8,3,2,5,6,4]

merge_sort(array_test)

print(array_test)


I'd say write out each iteration of the recursion on a whiteboard or something because your code is pretty straight forward. If you draw it out you'll see that the code is splitting up the array until it can't split anymore and then running those loops to change the order of the 2 halves but going back up to the next biggest halves.

A way to picture it is that each loop is taking care of a specific feature/situation and the recursion calls will save the current version of your list to run those same features on a smaller section of your list.

The first loop will handle going through your current state of the array and sorting the 2 halves based on which one goes first until one of them is done. The second loop handles the situations where the left side still has more elements to go through.

(i.e. [4,5], [1,2,3] )

And the third loop handles the situations where The right side has more elements left to go through

(i.e. [1,2], [3,4,5] )

Edit:

If I'm right about you asking about the order that the arrays are transversed, it goes:

[1,9,7,10,11] , [8,3,2,5,6,4] ->[1,9,] , [7,10,11] -> [1] , [9] (and sorts) -> [7] , [10,11] -> (skips sorting 7) -> [10] , [11] (and sorts) -> (sorts [7] , [10,11]) -> (sorts [1,9,] , [7,10,11]) -> etc.

Basically its cut the first array in the pair of arrays in half, and only the first, until you're able to get it down to the length of 1. Once you've done that and the first array of length 1 comes back, you can now finally start looking at a second array of a pair. Once you've finished with that pair and return from that recursive call you would have finished the "first" array for the layer above and while now start on the second array of that pair.

Once you go down the recursive call for that second array of that pair you'll repeat the process of prioritizing the first array of a pair