2

This is the function:

c = []
def badsort(l):
  v = 0
  m = len(l)
  while v<m:
    c.append(min(l))
    l.remove(min(l))
    v+=1
  return c

Although I realize that this is a very inefficient way to sort, I was wondering what the time complexity of such a function would be, as although it does not have nested loops, it repeats the loop multiple times.

cs95
  • 379,657
  • 97
  • 704
  • 746
Sam
  • 289
  • 3
  • 11

3 Answers3

4

Here are a couple of useful points to help you understand how to find the complexity of a function.

  1. Measure the number of iterations
  2. Measure the complexity of each operation at each iteration

For the first point, you see the terminating condition is v < m, where v is 0 initially, and m is the size of the list. Since v increments by one at each iteration, the loop runs at most (at least) N times, where N is the size of the list.

Now, for the second point. Per iteration we have -

c.append(min(l))

Where min is a linear operation, taking O(N) time. append is a constant operation.

Next,

l.remove(min(l))

Again, min is linear, and so is remove. So, you have O(N) + O(N) which is O(N).

In summary, you have O(N) iterations, and O(N) per iteration, making it O(N ** 2), or quadratic.

cs95
  • 379,657
  • 97
  • 704
  • 746
4

Terminology

Assume that n = len(l).

Iteration Count

The outer loops runs n times. The min() in the inner loop runs twice over l (room for optimisation here) but for incrementally decreasing numbers (for each iteration of the loop, the length of l decrements because you remove an item from the list every time).

That way the complexity is 2 * (n + (n-1) + (n-2) + ... + (n-n)). This equals 2 * (n^2 - (1 + 2 + 3 + ... + n)). The second term in the parenthesis is a triangular number and diverges to n*(n+1)/2.

Therefore your complexity equals 2*(n^2 - n*(n+1)/2)). This can be expanded to 2*(n^2 - n^2/2 - n/2), and simplified to n^2 - n.

BigO Notation

BigO notation is interested in the overall growth trend, rather than the precise growth rate of the function.

Drop Constants

In BigO notation, the constants are dropped. This leaves us still with n^2 - n since there are no constants.

Retain Only Dominant Terms

Also, in BigO notation only the dominant terms are considered. n^2 is dominant over n, so n is dropped.

Result

That means the answer in BigO is O(n) = n^2, i.e. quadratic complexity.

Dewald Abrie
  • 1,392
  • 9
  • 21
3

The time compexity for this problem is O(n^2). While the code itself has only one obvious loop, the while loop, the min and max functions are both O(n) by implementation, because at worst case, it would have to scan the entire list to find the corresponding minimum or maximum value. list.remove is O(n) because it too has to traverse the list until it finds the first target value, which at worst case, could be at the end. list.append is amortized O(1), due to a clever implementation of the method, because list.append is technically O(n)/n = O(1) for n objects pushed:

def badsort(l):
  v = 0
  m = len(l)
  while v<m: #O(n)
    c.append(min(l)) #O(n) + O(1) 
    l.remove(min(l)) #O(n) + O(n)
    v+=1
  return c

Thus, there is:

Outer(O(n)) * Inner(O(n)+O(n)+O(n)) = Outer(O(n)) * Inner(O(n))

O(n)+O(n)+O(n) can be combined to simply O(n) because big o measures worst case. Thus, by combining the outer and inner compexities, the final complexity is O(n^2).

Ajax1234
  • 69,937
  • 8
  • 61
  • 102
  • You should explain why those lines are O(N), and what specifically contributes to it. – cs95 Jan 09 '18 at 04:17
  • In the final line, you mentioned the final complexity is O(n) but in the first line, you mentioned O(n^2). What would be the overall time complexity? – Sam Jan 09 '18 at 04:18
  • Ok. That is great. Thanks! – Sam Jan 09 '18 at 04:20
  • @cᴏʟᴅsᴘᴇᴇᴅ That would be explaining specifically the implementation for `min`, `max`, `remove`, and `append`, which I believe is out of scope of the question. – Ajax1234 Jan 09 '18 at 04:21
  • No, you didn't understand. I just said to specifically mention why each line is O(N). For example, I did not see you mention that `remove` was O(N) when I wrote my comment. You added it in later. – cs95 Jan 09 '18 at 04:24
  • Good, your answer is satisfactory. Quick nitpick: `transverse -> traverse`. – cs95 Jan 09 '18 at 04:32
  • 2
    Shouldn't you multiply the time complexity for the inner and outer rather than add them? – Code-Apprentice Jan 09 '18 at 04:45