├── .gitignore ├── Data Structures - Arrays ├── Arrays.py ├── Implementing an array.py ├── Merge Sorted Arrays.py └── Reversing a string.py ├── Data Structures - Graph └── Graph Implementation.py ├── Data Structures - Hashtables ├── First Recurring Character.py └── Hash Table Implementation.py ├── Data Structures - Linked Lists ├── Doubly Linked List.py └── Linked List.py ├── Data Structures - Stacks and Queues ├── Queue using Linked List.py ├── Stacks using Arrays.py └── Stacks using Linked List.py ├── Data Structures - Trees ├── Binary Search Tree.py └── Heapq in python.py ├── README.md ├── Recursion ├── Factorial.py ├── Fibonacci.py └── Reversing a string using Recursion.py └── Sorting ├── Bubble sort.py ├── Insertion sort.py ├── Merge sort.py └── Selection sort.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /Data Structures - Arrays/Arrays.py: -------------------------------------------------------------------------------- 1 | strings = ['a','b','c','d'] 2 | # 4*4 = 16 bytes of storage is used 3 | 4 | print(strings[2]) 5 | 6 | #push 7 | strings.append('e') # O(1) 8 | #pop 9 | strings.pop() 10 | strings.pop() # O(1) 11 | 12 | #addfirstelement 13 | strings.insert(0,'x') #O(n) 14 | 15 | #splice 16 | strings.insert(2,'alien') #O(n) 17 | 18 | print(strings) -------------------------------------------------------------------------------- /Data Structures - Arrays/Implementing an array.py: -------------------------------------------------------------------------------- 1 | class MyArray: 2 | def __init__(self): 3 | self.length=0 4 | self.data={} 5 | 6 | def __str__(self): 7 | return str(self.__dict__) 8 | 9 | def push(self,item): 10 | self.data[self.length]=item 11 | self.length+=1 12 | 13 | def pop(self): 14 | lastitem = self.data[self.length-1] 15 | del self.data[self.length-1] 16 | self.length-=1 17 | return lastitem 18 | 19 | def delete(self,index): 20 | deleteditem = self.data[index] 21 | for i in range(index,self.length-1): 22 | self.data[i] = self.data[i+1] 23 | 24 | del self.data[self.length-1] 25 | self.length-=1 26 | return deleteditem 27 | 28 | 29 | 30 | 31 | 32 | arr=MyArray() 33 | arr.push(3) 34 | arr.push('hi') 35 | arr.push(34) 36 | arr.push(20) 37 | arr.push('hey') 38 | arr.push('welcome') 39 | arr.delete(3) 40 | print(arr) 41 | 42 | -------------------------------------------------------------------------------- /Data Structures - Arrays/Merge Sorted Arrays.py: -------------------------------------------------------------------------------- 1 | #def mergesortedarr(a,b): 2 | # x=a+b 3 | # x.sort() 4 | # return x 5 | 6 | #a=[1,2,3,4] 7 | #b=[3,7,9,12] 8 | #qw=mergesortedarr(a,b) 9 | #print(qw) 10 | 11 | #In interview we must solve only like this 12 | 13 | def mergesortedarr(a,b): 14 | if len(a)==0 or len(b)==0: 15 | return a+b 16 | mylist=[] 17 | i=0 18 | j=0 19 | while i= self.length: 37 | self.append(data) 38 | return 39 | else: 40 | leader = self.traversetoindex(index - 1) 41 | holder = leader.next 42 | leader.next = new_node 43 | new_node.next = holder 44 | new_node.prev = leader 45 | holder.prev = new_node 46 | self.length+=1 47 | 48 | def remove(self,index): 49 | if index == self.length-1: 50 | self.tail = self.tail.prev 51 | self.tail.next = None 52 | self.length -= 1 53 | return 54 | leader = self.traversetoindex(index-1) 55 | unwanted_node = leader.next 56 | holder = unwanted_node.next 57 | leader.next = holder 58 | holder.prev = leader 59 | self.length -= 1 60 | 61 | 62 | def traversetoindex(self,index): 63 | curr_node = self.head 64 | i = 0 65 | while i!= index: 66 | curr_node = curr_node.next 67 | i+=1 68 | return curr_node 69 | 70 | def printt(self): 71 | temp = self.head 72 | while temp != None: 73 | print(temp.data , end = ' ') 74 | temp = temp.next 75 | print() 76 | print('Length ' + str(self.length)) 77 | 78 | 79 | d = DoublyLinkedList() 80 | d.append(10) 81 | d.append(5) 82 | d.append(6) 83 | d.prepend(1) 84 | d.insert(2,22) 85 | d.remove(3) 86 | d.printt() 87 | -------------------------------------------------------------------------------- /Data Structures - Linked Lists/Linked List.py: -------------------------------------------------------------------------------- 1 | # 15 --> 6 --> 8 2 | 3 | class Node(): 4 | 5 | def __init__(self,data): 6 | self.data = data 7 | self.next = None 8 | 9 | class LinkedList(): 10 | 11 | def __init__(self): 12 | self.head = None 13 | self.tail = None 14 | 15 | def append(self,data): 16 | new_node = Node(data) 17 | if self.head == None: 18 | self.head = new_node 19 | self.tail = self.head 20 | self.length = 1 21 | else: 22 | self.tail.next = new_node 23 | self.tail = new_node 24 | self.length += 1 25 | 26 | def prepend(self,data): 27 | new_node = Node(data) 28 | new_node.next = self.head 29 | self.head = new_node 30 | 31 | 32 | self.length += 1 33 | 34 | def insert(self,index,data): 35 | new_node = Node(data) 36 | i = 0 37 | temp = self.head 38 | if index>=self.length: 39 | self.append(data) 40 | return 41 | while i') 41 | temp = temp.next 42 | print() 43 | print(self.length) 44 | 45 | myq = Queue() 46 | myq.enqueue('google') 47 | myq.enqueue('microsoft') 48 | myq.enqueue('facebook') 49 | myq.enqueue('apple') 50 | myq.printt() 51 | myq.dequeue() 52 | myq.printt() 53 | x = myq.peek() 54 | print(x) -------------------------------------------------------------------------------- /Data Structures - Stacks and Queues/Stacks using Arrays.py: -------------------------------------------------------------------------------- 1 | class Stack: 2 | def __init__(self): 3 | self.arr = [] 4 | self.length = 0 5 | 6 | def __str__(self): 7 | return str(self.__dict__) 8 | 9 | def peek(self): 10 | return self.arr[self.length-1] 11 | 12 | def push(self,value): 13 | self.arr.append(value) 14 | self.length += 1 15 | 16 | def pop(self): 17 | popped_item = self.arr[self.length-1] 18 | del self.arr[self.length-1] 19 | self.length -= 1 20 | return popped_item 21 | 22 | mystack = Stack() 23 | mystack.push('google') 24 | mystack.push('microsoft') 25 | mystack.push('facebook') 26 | mystack.push('apple') 27 | print(mystack) 28 | x = mystack.peek() 29 | print(x) 30 | mystack.pop() 31 | print(mystack) 32 | 33 | 34 | -------------------------------------------------------------------------------- /Data Structures - Stacks and Queues/Stacks using Linked List.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.data = data 4 | self.next = None 5 | 6 | class Stack: 7 | def __init__(self): 8 | self.top = None 9 | self.bottom = None 10 | self.length = 0 11 | 12 | def peek(self): 13 | return self.top.data 14 | 15 | def push(self,data): 16 | new_node = Node(data) 17 | if self.bottom == None: 18 | self.bottom = new_node 19 | self.top = self.bottom 20 | self.length = 1 21 | else: 22 | self.top.next = new_node 23 | self.top = self.top.next 24 | self.length += 1 25 | 26 | def pop(self): 27 | i = 1 28 | curr_node = self.bottom 29 | while i != self.length-1: 30 | curr_node = curr_node.next 31 | i+=1 32 | popped_value = curr_node.next 33 | curr_node.next = None 34 | self.top = curr_node 35 | self.length -= 1 36 | return popped_value.data 37 | 38 | def printt(self): 39 | temp = self.bottom 40 | while temp != None: 41 | print(temp.data , end = ' -> ') 42 | temp = temp.next 43 | print() 44 | mystack = Stack() 45 | mystack.push('google') 46 | mystack.push('microsoft') 47 | mystack.push('facebook') 48 | mystack.push('apple') 49 | mystack.printt() 50 | x = mystack.peek() 51 | print(x) 52 | y=mystack.pop() 53 | print(y) 54 | mystack.printt() 55 | qw = mystack.peek() 56 | print(qw) 57 | -------------------------------------------------------------------------------- /Data Structures - Trees/Binary Search Tree.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.data = data 4 | self.left = None 5 | self.right = None 6 | 7 | class BinarySearchTree: 8 | 9 | def __init__(self): 10 | self.root = None 11 | 12 | def insert(self,data): 13 | new_node = Node(data) 14 | if self.root == None: 15 | self.root = new_node 16 | return 17 | else: 18 | curr_node = self.root 19 | while True: 20 | if data < curr_node.data: 21 | #Left 22 | if curr_node.left == None: 23 | curr_node.left = new_node 24 | return 25 | else: 26 | curr_node = curr_node.left 27 | elif data > curr_node.data: 28 | #Right 29 | if curr_node.right == None: 30 | curr_node.right = new_node 31 | return 32 | else: 33 | curr_node = curr_node.right 34 | 35 | def lookup(self,data): 36 | curr_node = self.root 37 | while True: 38 | if curr_node == None: 39 | return False 40 | if curr_node.data == data: 41 | return True 42 | elif data < curr_node.data: 43 | curr_node = curr_node.left 44 | else: 45 | curr_node = curr_node.right 46 | 47 | def print_tree(self): 48 | if self.root != None: 49 | self.printt(self.root) 50 | #Inorder Traversal (We get sorted order of elements in tree) 51 | 52 | def printt(self,curr_node): 53 | if curr_node != None: 54 | self.printt(curr_node.left) 55 | print(str(curr_node.data)) 56 | self.printt(curr_node.right) 57 | 58 | 59 | bst = BinarySearchTree() 60 | bst.insert(10) 61 | bst.insert(5) 62 | bst.insert(6) 63 | bst.insert(12) 64 | bst.insert(8) 65 | x = bst.lookup(6) 66 | print(x) 67 | y = bst.lookup(99) 68 | print(y) 69 | bst.print_tree() 70 | -------------------------------------------------------------------------------- /Data Structures - Trees/Heapq in python.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | x = [5,2,8,1,6,7,4,9] 3 | #Heapify method sorts the list , this is min heap 4 | heapq.heapify(x) 5 | print(x) 6 | heapq.heappush(x,0) 7 | print(x) 8 | print(heapq.heappop(x)) 9 | print(x) 10 | # Used to pop and push the element in same time 11 | print (heapq.heappushpop(x, 5)) 12 | print(x) 13 | #Used to get n largest elements in heap 14 | print(heapq.nlargest(4,x)) 15 | #Used to get n smallest elements in heap 16 | print(heapq.nsmallest(4,x)) 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data-Structures-and-Algorithms 2 | Data Structures and Algorithms in Python 3 | -------------------------------------------------------------------------------- /Recursion/Factorial.py: -------------------------------------------------------------------------------- 1 | def factorial(num): 2 | if num == 1: 3 | return 1 4 | return num * factorial(num-1) 5 | 6 | def fact(num): 7 | result = 1 8 | for i in range(1,num+1): 9 | result = result * i 10 | return result 11 | 12 | print(fact(6)) 13 | 14 | print(factorial(4)) -------------------------------------------------------------------------------- /Recursion/Fibonacci.py: -------------------------------------------------------------------------------- 1 | def fib(num): 2 | a = 0 3 | b = 1 4 | sum = 0 5 | for i in range(0,num): 6 | sum = a+b 7 | a = b 8 | b = sum 9 | return sum 10 | 11 | def fibonacci(num): 12 | if num < 2: 13 | return num 14 | return fib(num-1) + fib(num-2) 15 | 16 | 17 | print(fib(5)) 18 | print(fibonacci(5)) -------------------------------------------------------------------------------- /Recursion/Reversing a string using Recursion.py: -------------------------------------------------------------------------------- 1 | def reverse(word): 2 | size = len(word) 3 | if size == 0 : 4 | return 5 | last_char = word[size-1] 6 | print(last_char,end='') 7 | return reverse(word[0:size-1]) 8 | 9 | reverse('hello there') -------------------------------------------------------------------------------- /Sorting/Bubble sort.py: -------------------------------------------------------------------------------- 1 | def bubblesort(arr): 2 | qw = 0 3 | while qw < len(arr): 4 | for i in range(0,len(arr)-1): 5 | if arr[i] > arr[i+1]: 6 | arr[i] , arr[i+1] = arr[i+1] , arr[i] 7 | 8 | qw += 1 9 | return arr 10 | 11 | arr = [5,9,1,2,7,3,8,2] 12 | print(bubblesort(arr)) 13 | 14 | -------------------------------------------------------------------------------- /Sorting/Insertion sort.py: -------------------------------------------------------------------------------- 1 | def insertionsort(arr): 2 | length = len(arr) 3 | i = 1 4 | end = arr[0] 5 | while i < length: 6 | if arr[i] < end: 7 | x = arr.pop(i) 8 | for j in range(0,i): 9 | if x < arr[j]: 10 | arr.insert(j,x) 11 | break 12 | end = arr[i] 13 | i += 1 14 | return arr 15 | 16 | arr = [6,5,3,1,8,7,2,4] 17 | print(insertionsort(arr)) 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Sorting/Merge sort.py: -------------------------------------------------------------------------------- 1 | arr = [99,44,6,2,1,5,63,87,283,4,0] 2 | 3 | def mergesort(arr): 4 | if len(arr) == 1: 5 | return arr 6 | length = len(arr) 7 | mid = length // 2 8 | left = arr[:mid] 9 | right = arr[mid:] 10 | print('Left {}'.format(left)) 11 | print('Right {}'.format(right)) 12 | 13 | return merge(mergesort(left),mergesort(right)) 14 | 15 | def merge(left,right): 16 | result = [] 17 | leftindex = 0 18 | rightindex = 0 19 | while leftindex < len(left) and rightindex < len(right): 20 | if left[leftindex] < right[rightindex]: 21 | result.append(left[leftindex]) 22 | leftindex += 1 23 | else: 24 | result.append(right[rightindex]) 25 | rightindex += 1 26 | print(left,right) 27 | print( result + left[leftindex:] + right[rightindex:] ) 28 | return result + left[leftindex:] + right[rightindex:] 29 | 30 | 31 | x = mergesort(arr) 32 | print(x) -------------------------------------------------------------------------------- /Sorting/Selection sort.py: -------------------------------------------------------------------------------- 1 | def selectionsort(arr): 2 | i = 0 3 | while i < len(arr): 4 | min = arr[i] 5 | index = i 6 | for j in range(i+1,len(arr)): 7 | if arr[j] < min: 8 | index = j 9 | min = arr[j] 10 | arr[i] , arr[index] = arr[index] , arr[i] 11 | i += 1 12 | 13 | return arr 14 | 15 | arr = [8,6,5,0,4,3,2] 16 | print(selectionsort(arr)) 17 | --------------------------------------------------------------------------------