Reputation: 103
I am currently facing an issue implementing insertion sort into quicksort. I am making it such that when the sublist is smaller than a certain value, insertion sort is called on the sublist instead of quicksort. I have managed to make it work by passing in the full list along with the indexes of the sublists, but when I try it by passing the sublist as a slice of the main list, it does not work.
Code that works (passing in the indexes of the sublist)
def quickSort(alist):
quickSortHelper(alist,0,len(alist)-1)
def quickSortHelper(alist,first,last):
if (last - first +1) < 5:
insertionSort(alist, first, last)
else:
splitpoint = partition(alist,first,last)
quickSortHelper(alist,first,splitpoint-1)
quickSortHelper(alist,splitpoint+1,last)
def partition(alist,first,last):
pivotvalue = alist[first]
leftmark = first+1
rightmark = last
done = False
while not done:
while leftmark <= rightmark and alist[leftmark] <= pivotvalue:
leftmark = leftmark + 1
while alist[rightmark] >= pivotvalue and rightmark >= leftmark:
rightmark = rightmark -1
if rightmark < leftmark:
done = True
else:
temp = alist[leftmark]
alist[leftmark] = alist[rightmark]
alist[rightmark] = temp
temp = alist[first]
alist[first] = alist[rightmark]
alist[rightmark] = temp
return rightmark
def insertionSort(alist, first, last):
for index in range(1,last +1):
currentvalue = alist[index]
position = index
while position>0 and alist[position-1]>currentvalue:
alist[position]=alist[position-1]
position = position-1
alist[position]=currentvalue
alist = [54,26,93,17,77,31,44,55,20,1,3,5]
quickSort(alist)
print(alist)
Code that doesnt work (passing the sublist in as a slice of the main list)
def quickSort(alist):
quickSortHelper(alist,0,len(alist)-1)
def quickSortHelper(alist,first,last):
if (last - first +1) < 5:
insertionSort(alist[first:last +1])
else:
splitpoint = partition(alist,first,last)
quickSortHelper(alist,first,splitpoint-1)
quickSortHelper(alist,splitpoint+1,last)
def partition(alist,first,last):
pivotvalue = alist[first]
leftmark = first+1
rightmark = last
done = False
while not done:
while leftmark <= rightmark and alist[leftmark] <= pivotvalue:
leftmark = leftmark + 1
while alist[rightmark] >= pivotvalue and rightmark >= leftmark:
rightmark = rightmark -1
if rightmark < leftmark:
done = True
else:
temp = alist[leftmark]
alist[leftmark] = alist[rightmark]
alist[rightmark] = temp
temp = alist[first]
alist[first] = alist[rightmark]
alist[rightmark] = temp
return rightmark
def insertionSort(alist):
for index in range(1, len(alist)):
currentvalue = alist[index]
position = index
while position>0 and alist[position-1]>currentvalue:
alist[position]=alist[position-1]
position = position-1
alist[position]=currentvalue
alist = [54,26,93,17,77,31,44,55,20,1,3,5]
quickSort(alist)
print(alist)
I have tried debugging it, basically what happens is once insertion sort is done with sorting the subarray and it returns to the previous recursive function, the array goes back to its previous 'unsorted' self. Would greatly appreciate any advice, thank you everyone.
Upvotes: 0
Views: 231
Reputation: 3462
Building on what was said in https://stackoverflow.com/a/68662714/14536215 you need return the sorted list from insertionSort and assign the the sorted values in your original list. You can use the same slicing for assigning you used in the function call:
alist[first:last +1] = insertionSort(alist[first:last +1])
Upvotes: 1
Reputation: 11496
In your first snippet, when you call
insertionSort(alist, first, last)
and then use
for index in range(1, last+1):
you're iterating last
times.
you're operating on the original alist
(any changes will reflect on alist
).
In your second snippet, when you call
insertionSort(alist[first:last +1])
and then use
for index in range(1, len(alist)):
last - first + 1
times.alist
(any changes will not reflect on alist
).Upvotes: 2