Switch to O(n) implenentation of sorted
This commit is contained in:
parent
022533dc4a
commit
d9fc5c45ef
22
qsort.py
22
qsort.py

@ 6,24 +6,32 @@ def qsort(xs):


right = [x for x in xs[1:] if x >= pivot]


return [qsort(left)] + [pivot] + [qsort(right)]




def _sorted(tree, acc):


if tree == []: return




_sorted(tree[0], acc)


acc.append(tree[1])


_sorted(tree[2], acc)




def sorted(tree):


if tree == []: return []


return sorted(tree[0]) + [tree[1]] + sorted(tree[2])


acc = []


_sorted(tree, acc)


return acc




def search(tree, x):


return _sorted(tree, x) != []


return _search(tree, x) != []




def insert(tree, x):


node = _sorted(tree, x)


node = _search(tree, x)


if node == []:


node.append([])


node.append(x)


node.append([])




def _sorted(tree, i):


def _search(tree, i):


if tree == []: return tree




pivot = tree[1]


if pivot == i: return tree


elif i < pivot: return _sorted(tree[0], i)


else: return _sorted(tree[2], i)


elif i < pivot: return _search(tree[0], i)


else: return _search(tree[2], i)




26
report.txt
26
report.txt

@ 12,7 +12,11 @@ A: Quicksort has the worstcase complexity of O(n^2). This is because in the wor




On average, Quicksort is also O(n*log(n)). It's quite difficult to consistently pick


a pivot that is either the smallest or the largest. I am unfamilliar with proof


techniques that help formalize this.


techniques that help formalize this, but we can think of a case in which


some nonhalf fraction (say j/k) of the elements


is on the left of the pivot. In this case, the depth ends up being a multiple


of log_k(n), meaning that the depth is still logarithmic and the complexity is


still O(n*log(n)).




Q: What's the bestcase, worstcase, and averagecase time complexities? Briefly explain.


A: For the same reason as quicksort, in the worst case, the complexity is O(n^2).



@ 25,19 +29,17 @@ A: For the same reason as quicksort, in the worst case, the complexity is O(n^2)


is n(1r^k)/(1r). This simplifies to 2n(1r^k). Since 12^k < 1,


n*(1+1/2+1/4+...) < 2n. This means the complexity is O(n).




For similarly handwavey reasons to those in Q0, the average case complexity aligns


with the bestcase complexity rather than worstcase complexity.


Similarly to quicksort, we can assume j/k elements are on the left


of the pivot. Then, the the longest possible computation will end up


looking at nj/k elements, then nj^2/k^2, and so on. This is effectively


n times the sum of the geometric series with r=j/k. This means


the sum is n * c, and thus, the complexity is O(n).




Q: What are the time complexities for the operations implemented?


A: The complexity of sorted is O(n*log(n)) in best, and O(n^2) in worst case.


This is because of the way in which it implements


"flattening" the binary search tree  it recursively calls itself, creating


a new array from the results of the two recursive calls and the "pivot" between them.


Since creating a new array from arrays of length m and n is an O(m+n) operation.


Just like with qsort, in the best case, the tree is balanced with a depth of log(n).


Since concatenation at each level will effectively take n steps, the best case complexity


is O(n*log(n)). On the other hand, in the case of a tree with only right children,


the concatenation will take 1+2+...+n steps, which is in the order O(n^2).


A: The complexity of sorted is O(n).


Since I use an accumulator array, array append is O(1). Then, all


that's done is an inorder traversal of the tree, which is O(n),


since it visits every element of the tree.




Since insert and search both use _search, and perform no steps above O(1), they are


of the same complexity as _search. _search itself is O(logn) in the average case,




Loading…
Reference in New Issue