This document provides information on various sorting algorithms including bubble sort, selection sort, and merge sort. It also discusses algorithm complexity analysis and searching algorithms like linear search and binary search. Key points discussed include the time complexity of different sorting algorithms, how to analyze total time complexity, and examples of using assertions for debugging.
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0 ratings0% found this document useful (0 votes)
135 views
6.0001 Final Cheat Sheet PDF
This document provides information on various sorting algorithms including bubble sort, selection sort, and merge sort. It also discusses algorithm complexity analysis and searching algorithms like linear search and binary search. Key points discussed include the time complexity of different sorting algorithms, how to analyze total time complexity, and examples of using assertions for debugging.
def bisect_search2(L, e): Example######### \ def bisect_search_helper(L, e, def bubble_sort(L, detail = False): and low, high): swap = False self.parent1.rid == other.parent2.rid if high == low: while not swap: return parents_same or return L[low] == e swap = True parents_opposite mid = (low + high)//2 for j in range(1, len(L)): def __str__(self): if L[mid] == e: if L[j-1] > L[j]: return "rabbit:"+ self.get_rid() return True swap = False #r1 = Rabbit(3) elif L[mid] > e: temp = L[j] #r2 = Rabbit(4) if low == mid: #nothing left L[j] = L[j-1] #print("r1 parent1:", to search L[j-1] = temp r1.get_parent1()) return False if detail == True: #print("r1 parent2:", else: print(L) r1.get_parent2()) return #### Selection Sort Example ###### LIST DOCUMENTATION bisect_search_helper(L, e, low, mid ###### ###### - 1) def selection_sort(L, detail = | append(...) else: False): | L.append(object) -> None -- return for i in range(len(L)): append object to end bisect_search_helper(L, e, mid + 1, for j in range(i, len(L)): | clear(...) high) if L[j] < L[i]: | L.clear() -> None -- remove all if len(L) == 0: L[i], L[j] = L[j], L[i] items from L return False if detail == True: | copy(...) else: print(L) | L.copy() -> list -- a shallow return bisect_search_helper(L, ####### Use of class variables copy of L e, 0, len(L) - 1) ####### | count(...) ###### Merge Sort Example ##### class Rabbit(Animal): | L.count(value) -> integer -- def merge(left, right): # a class variable, tag, shared return number of occurrences of result = [] across all instances value i,j = 0, 0 tag = 1 | extend(...) while i < len(left) and j < def __init__(self, age, | L.extend(iterable) -> None -- len(right): parent1=None, parent2=None): extend list by appending elements if left[i] < right[j]: Animal.__init__(self, age) from the iterable result.append(left[i]) self.parent1 = parent1 | index(...) i += 1 self.parent2 = parent2 | L.index(value, [start, [stop]]) -> else: self.rid = Rabbit.tag integer -- return first index of value. result.append(right[j]) Rabbit.tag += 1 | Raises ValueError if the value j += 1 def get_rid(self): is not present. # one list is empty # zfill used to add leading zeroes | insert(...) while (i < len(left)): 00001 instead of 1 | L.insert(index, object) -- insert result.append(left[i]) return str(self.rid).zfill(5) object before index i += 1 def get_parent1(self): | pop(...) while (j < len(right)): return self.parent1 | L.pop([index]) -> item -- result.append(right[j]) def get_parent2(self): remove and return item at index j += 1 return self.parent2 (default last). return result def __add__(self, other): | Raises IndexError if list is # returning object of same empty or index is out of range. def merge_sort(L, detail = False): type as this class | remove(...) if len(L) < 2: return Rabbit(0, self, other) | L.remove(value) -> None -- return L[:] def __eq__(self, other): remove first occurrence of value. else: # compare the ids of self and | Raises ValueError if the value middle = len(L)//2 other's parents is not present. # divide # don't care about the order of the | reverse(...) left = merge_sort(L[:middle], parents | L.reverse() -- reverse *IN detail) # the backslash tells python I want PLACE* right = merge_sort(L[middle:], to break up my line | sort(...) detail) parents_same = | L.sort(key=None, if detail == True: self.parent1.rid == other.parent1.rid reverse=False) -> None -- stable print("Merging", left, "and", \ sort *IN PLACE* right) and self.parent2.rid ##### DICT DOCUMENTATION # conquer == other.parent2.rid ####### | clear(...) ###############Sorts######### >>> letters[:2] ['a', 'b'] | D.clear() -> None. Remove all ##### >>> letters[:-2] ['a', 'b', 'c'] items from D. Random - shuffle, check if sorted >>> letters[::2] ['a', 'c', 'e'] | copy(...) O(unbounded) >>> letters[::-1] ['e', 'd', 'c', 'b', 'a'] | D.copy() -> a shallow copy of Bubble Sort – swap each pair >>> letters[1:4:2] ['b', 'd'] D until the list is in order; O(n) steps, | fromkeys(iterable, value=None, O(n) times; total complexity O(n^2) /) from builtins.type Selection Sort – sorted prefix and | Returns a new dict with keys unsorted suffix; add first element of from iterable and values equal to suffix to prefix; O(n) steps, O(n) value. times; total complexity O(n^2) | get(...) Merge Sort – break list in half | D.get(k[,d]) -> D[k] if k in D, (log n) times, recursively sort else d. d defaults to None. halves, merge sorted halves; O(log | items(...) n) levels, O(n) merging; total | D.items() -> a set-like object complexity O(n log n) providing a view on D's items ##########Complexity######### | keys(...) O(1) – basic operations, | D.keys() -> a set-like object assignment providing a view on D's keys Dictionaries:n is len(d) | pop(...) §worst case | D.pop(k[,d]) -> v, remove • index O(n) • store O(n) • length specified key and return the O(n) • delete O(n) • iteration O(n) corresponding value. § average case | If key is not found, d is • index O(1) • store O(1) • delete returned if given, otherwise O(1) • iteration O(n) KeyError is raised Lists:n is len(L) • index O(1) • store | popitem(...) O(1) • length O(1) • append O(1) • | D.popitem() -> (k, v), remove == O(n) • remove O(n) • copy O(n) and return some (key, value) pair • reverse O(n) • iteration O(n) • in as a list O(n) | 2-tuple; but raise KeyError if D Total time = time/call * (# calls) is empty. #############Search######### | #### | values(...) Linear O(n) – just loop through | D.values() -> an object Bisection O(log n) – list must be providing a view on D's values presorted ##### Raising your own If unsorted, must sort but that takes exceptions####### more time def get_ratios(L1, L2): #############Debugging###### """ Assumes: L1 and L2 are lists ####### of equal length of numbers Assertions – stops further Returns: a list containing computing L1[i]/L2[i] """ Assert <Boolean condition>, ratios = [] <argument> for index in range(len(L1)): Errors – raise your own try: Syntax, Name (can’t find name), Attribute (attribute doesn’t exist), ratios.append(L1[index]/L2[index]) Type, Value (type okay but value except ZeroDivisionError: illegal), Index, Key (no key in Dict) ratios.append(float('nan')) #nan = Not a Number Try: if anything has error, goes to except: exception raise ValueError('get_ratios Except _____: can specify error called with bad arg') Else: if no exceptions raised else: Finally: always executed after print("success") everything else finally: #############Splicing######### print("executed no matter #### what!") >>> letters = ['a', 'b', 'c', 'd', 'e'] return ratios >>> letters[:] ['a', 'b', 'c', 'd', 'e'] >>> letters[2:] ['c', 'd', 'e']