Giter Site home page Giter Site logo

undergradpythonds's Introduction

Python Undergrad DataStructures and Algo Implementations

Since people seem to care about this stuff, I've added implementations of important undergrad algorithms in Python. I'm using Problem Solving with Algorithms and Data Structures as a guide. Open an issue if you'd like me to implement a specific one.

  • Please use this for what it is: a study guide. Code has not been extensively. *

So far I have:

The Basics

  • Stacks (nothing too surprising)
aStack = Stack()
aStack.push(5)
aStack.pop()
assert(aStack.isEmpty() == true)
  • Queues, more of the same...
  • Deques, do you really need me to implement those too?
  • Min-heap: the code is much more easily understood if you take into account that a complete tree can be represented by a list where for an element at position i its children are at position 2i and 2i + 1. Imagine spreading out all the elements of a tree Breadth First.

I should point out this SO link. Textbooks generally state that building a heap is O(n log n) time which is correct if you are inserting the elements in a heap one by one. BUT if you just put all the elements in, in an arbitrary order and heapify then you can bring that cost down to O(N)

def buildHeap(self,alist):
        i = len(alist) // 2 #nodes in alist[:i] are all leaves
        self.currentSize = len(alist)
        self.heapList = [0] + alist[:] #[0] at beginning helps arithmetic work
        while (i > 0):
            #every element will be pushed to the correct location after percdown
            self.percDown(i) 
            #do this for all non-leaf elements
            i = i - 1

myHeap = BinHeap()
a = [1,4,11,2,3,6,0]
myHeap.buildHeap(a)

Sorting

  • MergeSort: Classic divide and conquer, merge can be performed in place without an extra list if one is so inclined.
  • QuickSort Elegant but inefficient filter based solution O(N!)
pivots  = [x for x in alist if x == alist[0]]
        lesser  = self.filterQuickSort([x for x in alist if x < alist[0]])
        greater = self.filterQuickSort([x for x in alist if x > alist[0]])
        return lesser + pivots + greater

Efficient in memory solution that works by swapping elements with the pivot appropriately to avoid creating two news lists. (in progress, needs a fix)

def _partition(alist,begin,end):
            pivot = begin
            for i in range(begin + 1 , end + 1):
                if alist[i] <= alist[begin]:
                    pivot += 1
                    alist[i],alist[pivot] = alist[pivot], alist[i]
            alist[pivot],alist[begin] = alist[begin],alist[pivot]
            return pivot

Dynamic Programming

  • Smallest amount of change problem: Suppose you had 1, 5, 10, and 25 cent coins what's the smallest number of coins you'd need to give me 63 cents in change. The greedy solution is optimal for the 1,5,10,25 values, if you add a 21 cent coin then the greedy solution will fail. So greedy won't work for a general case solution so we have 3 methods sorted in increasing awesomeness.
#will need to use bigger lists to see effect irl
GetChangeInstance = GetChange()

#u slow m8
print(GetChangeInstance.recMC([1,5,10,25,21],63))

#better
print(GetChangeInstance.recMCMemoized([1,5,10,25,21],63))

#duuuude
print(GetChangeInstance.DPMC([1,5,10,25,21],63))

Note: You can create class to help make all functions memoisable followingthis SO link

#first approach using decorators
@memoise
def yourFunction(arg1,arg2):
    #some code

#Second approach (Python 3 only)
import functools

@functools.lru_cache(maxsize=None) #last 128 by default
def fib(num):
    # ...

#From scratch
class Memoize:
    def __init__(self, f):
        self.f = f
        self.memo = {}
    def __call__(self, *args):
        if not args in self.memo:
            self.memo[args] = self.f(*args)
        return self.memo[args]

def yourFunction(arg1,arg2):
    #somestuff

yourFunction = Memoize(yourFunction(arg1,arg2))

Trees

  • Binary Search Tree with a gloriously simple API:
aTree = BinarySearchTree()
    aTree[1] = "python"
    aTree[3] = "datastructures"
    aTree[6] = "are dope"

    aTree[1] = aTree[3]
    del aTree[3]
    for keys,vals in aTree:
        print("Key: %i Value: %s %(keys,vals)")

All Three different tree traversal algorithms, don't ever let this stuff confuse you again! Rename __iter__ to _inorder and rename _postorder to __iter__ to change the default inorder tree traversal when you iterate over the tree

def _postOrder(self):
        if self:
            if self.hasLeftChild:
                for elem in self.leftChild:
                    yield elem
            if self.hasRightChild:
                for elem in self.rightChild:
                    yield elem
            yield self.key

Graph Algorithms

  • Graph Data Structure in Adjacency List format with a simple API
MyGraph = Graph()
MyGraph.addEdge(vertex1 = 5,vertex 2 3, weight = 10)
MyVertex = Vertex(5)
assert(Vertex(5) in myGraph == true)

Graph Search Algorithms

  • Breadth First Search: below is the basic idea behind how breadth first search is implemented using queue.
currentVert = vertQueue.dequeue()
        for nbr in currentVert.getConnections():
            if (nbr.getColor == 'white'):
                nbr.setColor('gray')
                nbr.setDistance(currentVert.getDistance() + 1)
                nbr.setPred(currentVert)
                vertQueue.enqueue(nbr)

*Replace the Queue by a stack! Do it! You get Depth First Search, big thanks to Adam Nemecek for this nice tidbit.

Spanning Tree

  • Prim's Algorithm: Did you know that Prim and Dijkstra differ in only one line in their implementation?
def prim(G,start):
    pq = PriorityQueue()

    #initialize values
    for v in G:
        v.setDistance(sys.maxsize)
        v.setPred(None) 
    start.setDistance(0)
    pq.buildHeap([(v.getDistance(),v) for v in G])
    while not pq.isEmpty(): 
        currentVert = pq.delMin()
        for nextVert in currentVert.getConnections():
            newCost = currentVert.getWeight(nextVert) + currentVert.getDistance()
            
            #in dijkstra the below line would be
            #if newCost < nextVert.getDistance():
            if nextVert in pq and newCost < nextVert.getDistance():
                nextVert.setPred(currentVert)
                nextVert.setDistance(newCost)
                pq.decreaseKey(nextVert,newCost)

Consult SO for info on why I use decrease-key here.

Cause why not

Implementing a basic arithmetic language

  • Implementing basic arithmetic in case people expect you to know the basics behind how a compiler works
pt = buildParseTree("( ( 10 + 5 ) * 3 )")
assert(evaluate(pt) == 45)

Eval~Apply

Good to Know Stuff

a = [1,2,3,4]
>>> a[0:2] # take items 0-2, upper bound noninclusive
[1, 2]
>>> a[0:-1] #take all but the last
[1, 2, 3]
>>> a[1:4]
[2, 3, 4]
>>> a[::-1] # reverse the list
[4, 3, 2, 1]
>>> a[::2] # skip 2
[1, 3]

undergradpythonds's People

Contributors

msaroufim avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.