Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a typical way to add a reverse feature to an insertion sort?

I wrote the following insertion sort algorithm

def insertionSort(L, reverse=False):
    for j in xrange(1,len(L)):
        valToInsert = L[j]
        i=j-1
        while i>=0 and L[i] > valToInsert:
            L[i+1] = L[i]
            i-=1
        L[i+1] = valToInsert
    return L

Edit: All you need to do is change the final > to < to get it to work in reverse.

However, what do most people do in these situations? Write the algorithm twice in two if-statements, one where it's > and the other where it's < instead? What is the "correct" way to typically handle these kinds of scenarios where the change is minor but it simply changes the nature of the loop/code entirely?

I know this question is a little subjective.

like image 466
MyNameIsKhan Avatar asked Mar 19 '13 20:03

MyNameIsKhan


People also ask

Which technique is used in insertion sort?

Insertion sort is a simple sorting algorithm that works similar to the way you sort playing cards in your hands. The array is virtually split into a sorted and an unsorted part. Values from the unsorted part are picked and placed at the correct position in the sorted part.

How do you sort a list in reverse?

In order to reverse the original order of a list, you can use the reverse() method. The reverse() method is used to reverse the sequence of the list and not to arrange it in a sorted order like the sort() method. reverse() method reverses the sequence of the list permanently.

How do you modify insertion sort?

Time complexity of Insertion sort is O(n2) and space complexity is O(n). Performance of insertion sort can be improved by quickly finding the location of an element and then by minimizing the number of shift operations required to be performed in its each iteration.


2 Answers

You could use a variable for the less-than operator:

import operator
def insertionSort(L, reverse=False):       
    lt = operator.gt if reverse else operator.lt        
    for j in xrange(1,len(L)):
        valToInsert = L[j]
        i = j-1
        while 0 <= i and lt(valToInsert, L[i]):
            L[i+1] = L[i]
            i -= 1
        L[i+1] = valToInsert
    return L
like image 122
unutbu Avatar answered Nov 15 '22 07:11

unutbu


Option 1:

def insertionSort(L, reverse=False):
    # loop is the same...
    if reverse:
        L.reverse()
    return L

Option 2:

def insertionSort(L, reverse=False):
    if reverse:
        cmpfunc = lambda a, b: cmp(b, a)
    else:
        cmpfunc = cmp
    for j in xrange(1,len(L)):
        valToInsert = L[j]
        i=j-1
        while i>=0 and cmpfunc(L[i], valToInsert) > 0:
            L[i+1] = L[i]
            i-=1
        L[i+1] = valToInsert
    return L
like image 37
shx2 Avatar answered Nov 15 '22 06:11

shx2