This isn't really merging two separate arrays, but rather merging two pieces of one array into another array. The concept is the same, but the code you posted takes advantage of the fact that it's actually a single array.
The best way I found to understand how this works is to work an example by hand, on paper, with a pencil.
So imagine your nums
array looks like this:
nums = [...,1,3,4,7,12,0,2,5,6,9,13,...]
There's stuff before the 1
and stuff after the 13
, but right now in the algorithm it's trying to sort that bit. We'll assume that the 1
is at index 100
in the array. That would make left=100
and 'right=110`.
The code builds a tmp
array containing that range of items, and initializes the indexes:
tmp = [1,3,4,7,12,0,2,5,6,9,13]
left_start = 0
left_end = 4
right_start = 5
right_end = 10
i = 0
j = 5
Now we get to the loop. The loop expression is:
for k in range(left, right + 1):
k
here is really just a counter and an index. Each time through the loop the code will pick the lowest of the two numbers (that is, tmp[i]
or tmp[j]
) and write it to nums[k]
. When k
reaches the end of the range, the merge is complete.
So, to start:
tmp = [1,3,4,7,12,0,2,5,6,9,13]
| |
i j
And here's the whole loop, with line numbers for discussion:
1 for k in range(left, right + 1):
2
3 if i > left_end:
4 nums[k] = tmp[j]
5 j += 1
6
7 elif j > right_end or tmp[i] <= tmp[j]:
8 nums[k] = tmp[i]
9 i += 1
10
11 else:
12 nums[k] = tmp[j]
13 j += 1
The comparison at line 3 checks to see if i
, the index into the left subarray, has reached the end of that subarray. If it has then there's no comparison to do: just copy from the right subarray into the destination, and increment the right subarray index.
The comparison at line 7 does two things. First, it checks to see if the right index has passed the end of the right subarray. It's the same check as was done on line 3, but for the right subarray. So, if we've reached the end of the right subarray, OR if the item at tmp[i]
is less than or equal to the item at tmp[j]
(i.e. the item in the left subarray is smaller than the item in the right subarray), then copy from the left subarray to the destination, and increment the left subarray index.
The code starting at line 11 is the fallback case. Neither of the subarrays has been exhausted and the the right subarray item is smaller than the left subarray item. So copy from the right subarray and increment the right index (j
).
I encourage you to write down the small sample array I supplied and single-step the execution of this loop on paper, going through each of the logic steps. Better yet, get yourself a deck of cards and do the merge by hand. The steps you go through are exactly what the merge loop you posted is doing.