Skip to content

Commit

Permalink
Merge pull request TheAlgorithms#97 from OmkarPathak/added_programs
Browse files Browse the repository at this point in the history
Added Stack implementation and some traditional Stack problems
  • Loading branch information
0oo0 authored Aug 8, 2017
2 parents ab42e3a + ef01688 commit 43b53f7
Show file tree
Hide file tree
Showing 7 changed files with 343 additions and 0 deletions.
40 changes: 40 additions & 0 deletions data_structures/Graph/Graph.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Author: OMKAR PATHAK

# We can use Python's dictionary for constructing the graph

class AdjacencyList(object):
def __init__(self):
self.List = {}

def addEdge(self, fromVertex, toVertex):
# check if vertex is already present
if fromVertex in self.List.keys():
self.List[fromVertex].append(toVertex)
else:
self.List[fromVertex] = [toVertex]

def printList(self):
for i in self.List:
print(i,'->',' -> '.join([str(j) for j in self.List[i]]))

if __name__ == '__main__':
al = AdjacencyList()
al.addEdge(0, 1)
al.addEdge(0, 4)
al.addEdge(4, 1)
al.addEdge(4, 3)
al.addEdge(1, 0)
al.addEdge(1, 4)
al.addEdge(1, 3)
al.addEdge(1, 2)
al.addEdge(2, 3)
al.addEdge(3, 4)

al.printList()

# OUTPUT:
# 0 -> 1 -> 4
# 1 -> 0 -> 4 -> 3 -> 2
# 2 -> 3
# 3 -> 4
# 4 -> 1 -> 3
61 changes: 61 additions & 0 deletions data_structures/Graph/P01_BreadthFirstSearch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Author: OMKAR PATHAK

class Graph():
def __init__(self):
self.vertex = {}

# for printing the Graph vertexes
def printGraph(self):
for i in self.vertex.keys():
print(i,' -> ', ' -> '.join([str(j) for j in self.vertex[i]]))

# for adding the edge beween two vertexes
def addEdge(self, fromVertex, toVertex):
# check if vertex is already present,
if fromVertex in self.vertex.keys():
self.vertex[fromVertex].append(toVertex)
else:
# else make a new vertex
self.vertex[fromVertex] = [toVertex]

def BFS(self, startVertex):
# Take a list for stoting already visited vertexes
visited = [False] * len(self.vertex)

# create a list to store all the vertexes for BFS
queue = []

# mark the source node as visited and enqueue it
visited[startVertex] = True
queue.append(startVertex)

while queue:
startVertex = queue.pop(0)
print(startVertex, end = ' ')

# mark all adjacent nodes as visited and print them
for i in self.vertex[startVertex]:
if visited[i] == False:
queue.append(i)
visited[i] = True

if __name__ == '__main__':
g = Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(2, 3)
g.addEdge(3, 3)

g.printGraph()
print('BFS:')
g.BFS(2)

# OUTPUT:
# 0  ->  1 -> 2
# 1  ->  2
# 2  ->  0 -> 3
# 3  ->  3
# BFS:
# 2 0 3 1
61 changes: 61 additions & 0 deletions data_structures/Graph/P02_DepthFirstSearch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Author: OMKAR PATHAK

class Graph():
def __init__(self):
self.vertex = {}

# for printing the Graph vertexes
def printGraph(self):
print(self.vertex)
for i in self.vertex.keys():
print(i,' -> ', ' -> '.join([str(j) for j in self.vertex[i]]))

# for adding the edge beween two vertexes
def addEdge(self, fromVertex, toVertex):
# check if vertex is already present,
if fromVertex in self.vertex.keys():
self.vertex[fromVertex].append(toVertex)
else:
# else make a new vertex
self.vertex[fromVertex] = [toVertex]

def DFS(self):
# visited array for storing already visited nodes
visited = [False] * len(self.vertex)

# call the recursive helper function
for i in range(len(self.vertex)):
if visited[i] == False:
self.DFSRec(i, visited)

def DFSRec(self, startVertex, visited):
# mark start vertex as visited
visited[startVertex] = True

print(startVertex, end = ' ')

# Recur for all the vertexes that are adjacent to this node
for i in self.vertex.keys():
if visited[i] == False:
self.DFSRec(i, visited)

if __name__ == '__main__':
g = Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(2, 3)
g.addEdge(3, 3)

g.printGraph()
print('DFS:')
g.DFS()

# OUTPUT:
# 0  ->  1 -> 2
# 1  ->  2
# 2  ->  0 -> 3
# 3  ->  3
# DFS:
# 0 1 2 3
27 changes: 27 additions & 0 deletions data_structures/Stacks/Balanced_Parentheses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Author: OMKAR PATHAK

import Stack

def parseParenthesis(string):
balanced = 1
index = 0
myStack = Stack.Stack(len(string))
while (index < len(string)) and (balanced == 1):
check = string[index]
if check == '(':
myStack.push(check)
else:
if myStack.isEmpty():
balanced = 0
else:
myStack.pop()
index += 1

if balanced == 1 and myStack.isEmpty():
return True
else:
return False

if __name__ == '__main__':
print(parseParenthesis('((()))')) # True
print(parseParenthesis('((())')) # False
48 changes: 48 additions & 0 deletions data_structures/Stacks/Infix_To_Postfix_Conversion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Author: OMKAR PATHAK

import Stack

def isOperand(char):
return (ord(char) >= ord('a') and ord(char) <= ord('z')) or (ord(char) >= ord('A') and ord(char) <= ord('Z'))

def precedence(char):
if char == '+' or char == '-':
return 1
elif char == '*' or char == '/':
return 2
elif char == '^':
return 3
else:
return -1

def infixToPostfix(myExp, myStack):
postFix = []
for i in range(len(myExp)):
if (isOperand(myExp[i])):
postFix.append(myExp[i])
elif(myExp[i] == '('):
myStack.push(myExp[i])
elif(myExp[i] == ')'):
topOperator = myStack.pop()
while(not myStack.isEmpty() and topOperator != '('):
postFix.append(topOperator)
topOperator = myStack.pop()
else:
while (not myStack.isEmpty()) and (precedence(myExp[i]) <= precedence(myStack.peek())):
postFix.append(myStack.pop())
myStack.push(myExp[i])

while(not myStack.isEmpty()):
postFix.append(myStack.pop())
return ' '.join(postFix)

if __name__ == '__main__':
myExp = 'a+b*(c^d-e)^(f+g*h)-i'
myExp = [i for i in myExp]
print('Infix:',' '.join(myExp))
myStack = Stack.Stack(len(myExp))
print('Postfix:',infixToPostfix(myExp, myStack))

# OUTPUT:
# Infix: a + b * ( c ^ d - e ) ^ ( f + g * h ) - i
# Postfix: a b c d ^ e - f g h * + ^ * + i -
50 changes: 50 additions & 0 deletions data_structures/Stacks/Stack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Author: OMKAR PATHAK

class Stack(object):
def __init__(self, limit = 10):
self.stack = []
self.limit = limit

# for printing the stack contents
def __str__(self):
return ' '.join([str(i) for i in self.stack])

# for pushing an element on to the stack
def push(self, data):
if len(self.stack) >= self.limit:
print('Stack Overflow')
else:
self.stack.append(data)

# for popping the uppermost element
def pop(self):
if len(self.stack) <= 0:
return -1
else:
return self.stack.pop()

# for peeking the top-most element of the stack
def peek(self):
if len(self.stack) <= 0:
return -1
else:
return self.stack[len(self.stack) - 1]

# to check if stack is empty
def isEmpty(self):
return self.stack == []

# for checking the size of stack
def size(self):
return len(self.stack)

if __name__ == '__main__':
myStack = Stack()
for i in range(10):
myStack.push(i)
print(myStack)
myStack.pop() # popping the top element
print(myStack)
myStack.peek() # printing the top element
myStack.isEmpty()
myStack.size()
56 changes: 56 additions & 0 deletions sorts/bucket_sort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env python
# Author: OMKAR PATHAK
# This program will illustrate how to implement bucket sort algorithm

# Wikipedia says: Bucket sort, or bin sort, is a sorting algorithm that works by distributing the
# elements of an array into a number of buckets. Each bucket is then sorted individually, either using
# a different sorting algorithm, or by recursively applying the bucket sorting algorithm. It is a
# distribution sort, and is a cousin of radix sort in the most to least significant digit flavour.
# Bucket sort is a generalization of pigeonhole sort. Bucket sort can be implemented with comparisons
# and therefore can also be considered a comparison sort algorithm. The computational complexity estimates
# involve the number of buckets.

# Time Complexity of Solution:
# Best Case O(n); Average Case O(n); Worst Case O(n)

from P26_InsertionSort import insertionSort
import math

DEFAULT_BUCKET_SIZE = 5

def bucketSort(myList, bucketSize=DEFAULT_BUCKET_SIZE):
if(len(myList) == 0):
print('You don\'t have any elements in array!')

minValue = myList[0]
maxValue = myList[0]

# For finding minimum and maximum values
for i in range(0, len(myList)):
if myList[i] < minValue:
minValue = myList[i]
elif myList[i] > maxValue:
maxValue = myList[i]

# Initialize buckets
bucketCount = math.floor((maxValue - minValue) / bucketSize) + 1
buckets = []
for i in range(0, bucketCount):
buckets.append([])

# For putting values in buckets
for i in range(0, len(myList)):
buckets[math.floor((myList[i] - minValue) / bucketSize)].append(myList[i])

# Sort buckets and place back into input array
sortedArray = []
for i in range(0, len(buckets)):
insertionSort(buckets[i])
for j in range(0, len(buckets[i])):
sortedArray.append(buckets[i][j])

return sortedArray

if __name__ == '__main__':
sortedArray = bucketSort([12, 23, 4, 5, 3, 2, 12, 81, 56, 95])
print(sortedArray)

0 comments on commit 43b53f7

Please sign in to comment.