Reputation: 3
I am trying to merge two sorted arrays recursively, and I can merge the first few numbers until one pointer exits the array. There seems to be some problem with the base case not getting executed. I have tried to print the new_arr
with the pointers for each recursive call to debug but cannot seem to find a solution. Here is my code:
new_arr= []
i= 0
j=0
def merge(arr1, arr2, i, j):
#base case
##when arr1 pointer exits
print(i,j, new_arr)
if(i>len(arr1)-1):
new_arr.append(arr2[j:])
return new_arr
##when arr2 pointer exits
if (j > len(arr2)-1):
new_arr.append(arr1[i:])
return new_arr
if(arr1[i]<arr2[j]):
new_arr.append(arr1[i])
i+=1
merge(arr1, arr2, i, j)
elif(arr1[i]>=arr2[j]):
new_arr.append(arr2[j])
j+=1
merge(arr1, arr2, i, j)
sortedarr = merge([1,9], [3,7,11,14,18,99], i, j)
print(sortedarr)
and here goes my output:
0 0 []
1 0 [1]
1 1 [1, 3]
1 2 [1, 3, 7]
2 2 [1, 3, 7, 9]
None
Upvotes: 0
Views: 313
Reputation: 11289
Note that Python already has a built-in function that knows how to merge sorted arrays, heapq.merge.
list(heapq.merge((1, 3, 5, 7), (2, 4, 6, 8)))
[1, 2, 3, 4, 5, 6, 7, 8]
Upvotes: 1
Reputation: 350310
These are the issues:
new_arr.append(arr2[j:])
should be new_arr.extend(arr2[j:])
. append
is for appending one item to the list, while extend
concatenates a second list to the first. The same change needs to happen in the second case.
As you count on getting the mutated list as a returned value, you should not discard the list that is returned by the recursive call. You should return it back to the caller, until the first caller gets it.
It is a bad idea to have new_arr
a global value. If the main program would call the function a second time for some other input, new_arr
will still have its previous values, polluting the result of the next call.
Although the first two fixes will make your function work (for a single test), the last issue would best be fixed by using a different pattern:
Let the recursive call return the list that merges the values that still needed to be analysed, i.e. from i
and j
onwards. The caller is then responsible of prepending its own value to that returned (partial) list. This way there is no more need of a global variable:
def merge(arr1, arr2, i, j):
if i >= len(arr1):
return arr2[j:]
if j >= len(arr2):
return arr1[i:]
if arr1[i] < arr2[j]:
return [arr1[i]] + merge(arr1, arr2, i + 1, j)
else:
return [arr2[j]] + merge(arr1, arr2, i, j + 1)
sortedarr = merge([1,9], [3,7,11,14,18,99], i, j)
print(sortedarr)
Upvotes: 2