2

I have implemented insertion sort in python and was wondering how to determine the complexity of the algorithm. Is this an inefficient way of implementing insertion sort? To me, this seems like the most readable algorithm.

import random as rand
source = [3,1,0,10,20,2,1]
target = []
while len(source)!=0:
 if len(target) ==0:
  target.append(source[0])
  source.pop(0)
 element = source.pop(0)
 if(element <= target[0]):
  target.reverse()
  target.append(element)
  target.reverse()
 elif element > target[len(target)-1]:
  target.append(element) 
 else:
  for i in range(0,len(target)-1):
   if element >= target[i] and element <= target[i+1]:
    target.insert(i+1,element)
    break
print target 
4
  • 1
    Not your question, but since you've mentioned "readability": in python, while len(source)!=0 is equivalent to while source if you know that source is a list or string, etc. Also, if len(target) == 0 can be if not target Commented Mar 5, 2013 at 21:10
  • 2
    Reading PEP-8 is also recommended. Indent by 4 spaces, for example. Commented Mar 5, 2013 at 21:18
  • You may wish to look at the bisect module Commented Mar 5, 2013 at 21:28
  • you only intend for the first if statement inside your while loop to be called once. So move it out of the loop - place it before the loop. As it is now, given a one element list, your function will try to pop an element from it - twice. Commented Mar 5, 2013 at 21:30

3 Answers 3

2

Instead of:

target.reverse()
target.append(element)
target.reverse()

try:

target.insert(0, element)

Also, maybe use a for loop, instead of a while loop, to avoid source.pop()?:

for value in source:
  ...

In the final else block, the first part of the if test is redundant:

else:
   for i in range(0,len(target)-1):
     if element >= target[i] and element <= target[i+1]:
        target.insert(i+1,element)
        break

Since the list is already sorted, as soon as you find an element larger than the one you're inserting, you've found the insertion location.

Sign up to request clarification or add additional context in comments.

2 Comments

inserting 10 into [1,4,17], without the second part of that test, 10 would be inserted after 1. So the 2nd part of that test is needed.
Good point, @WillNess. It's the first part that is redundant. My note after the comment block was my main point. I updated the answer.
1

I would say it is rather inefficient. How can you tell? Your approach creates a second array, but you don't need one in a selection sort. You use a lot of operations -- selection sort requires lookups and exchanges, but you have lookups, appends, pops, inserts, and reverses. So you know that you can probably do better.

Comments

1
def insertionsort( aList ):
  for i in range( 1, len( aList ) ):
    tmp = aList[i]
    k = i
    while k > 0 and tmp < aList[k - 1]:
        aList[k] = aList[k - 1]
        k -= 1
    aList[k] = tmp

This code is taken from geekviewpoint.com. Clearly it's a O(n^2) algorithm since it's using two loops. If the input is already sorted, however, then it's O(n) since the while-loop would then always be skipped due to tmp < aList[k - 1] failing.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.