Updated README

This commit is contained in:
Anup Kumar Panwar
2019-07-06 11:11:20 +05:30
parent 831558d38d
commit 4e413c0183
45 changed files with 404 additions and 702 deletions

View File

View File

@@ -1,3 +0,0 @@
arr = [10, 20, 30, 40]
arr[1] = 30 # set element 1 (20) of array to 30
print(arr)

View File

@@ -1,181 +0,0 @@
"""
An AVL tree
"""
from __future__ import print_function
class Node:
def __init__(self, label):
self.label = label
self._parent = None
self._left = None
self._right = None
self.height = 0
@property
def right(self):
return self._right
@right.setter
def right(self, node):
if node is not None:
node._parent = self
self._right = node
@property
def left(self):
return self._left
@left.setter
def left(self, node):
if node is not None:
node._parent = self
self._left = node
@property
def parent(self):
return self._parent
@parent.setter
def parent(self, node):
if node is not None:
self._parent = node
self.height = self.parent.height + 1
else:
self.height = 0
class AVL:
def __init__(self):
self.root = None
self.size = 0
def insert(self, value):
node = Node(value)
if self.root is None:
self.root = node
self.root.height = 0
self.size = 1
else:
# Same as Binary Tree
dad_node = None
curr_node = self.root
while True:
if curr_node is not None:
dad_node = curr_node
if node.label < curr_node.label:
curr_node = curr_node.left
else:
curr_node = curr_node.right
else:
node.height = dad_node.height
dad_node.height += 1
if node.label < dad_node.label:
dad_node.left = node
else:
dad_node.right = node
self.rebalance(node)
self.size += 1
break
def rebalance(self, node):
n = node
while n is not None:
height_right = n.height
height_left = n.height
if n.right is not None:
height_right = n.right.height
if n.left is not None:
height_left = n.left.height
if abs(height_left - height_right) > 1:
if height_left > height_right:
left_child = n.left
if left_child is not None:
h_right = (left_child.right.height
if (left_child.right is not None) else 0)
h_left = (left_child.left.height
if (left_child.left is not None) else 0)
if (h_left > h_right):
self.rotate_left(n)
break
else:
self.double_rotate_right(n)
break
else:
right_child = n.right
if right_child is not None:
h_right = (right_child.right.height
if (right_child.right is not None) else 0)
h_left = (right_child.left.height
if (right_child.left is not None) else 0)
if (h_left > h_right):
self.double_rotate_left(n)
break
else:
self.rotate_right(n)
break
n = n.parent
def rotate_left(self, node):
aux = node.parent.label
node.parent.label = node.label
node.parent.right = Node(aux)
node.parent.right.height = node.parent.height + 1
node.parent.left = node.right
def rotate_right(self, node):
aux = node.parent.label
node.parent.label = node.label
node.parent.left = Node(aux)
node.parent.left.height = node.parent.height + 1
node.parent.right = node.right
def double_rotate_left(self, node):
self.rotate_right(node.getRight().getRight())
self.rotate_left(node)
def double_rotate_right(self, node):
self.rotate_left(node.getLeft().getLeft())
self.rotate_right(node)
def empty(self):
if self.root is None:
return True
return False
def preShow(self, curr_node):
if curr_node is not None:
self.preShow(curr_node.left)
print(curr_node.label, end=" ")
self.preShow(curr_node.right)
def preorder(self, curr_node):
if curr_node is not None:
self.preShow(curr_node.left)
self.preShow(curr_node.right)
print(curr_node.label, end=" ")
def getRoot(self):
return self.root
t = AVL()
t.insert(1)
t.insert(2)
t.insert(3)
# t.preShow(t.root)
# print("\n")
# t.insert(4)
# t.insert(5)
# t.preShow(t.root)
# t.preorden(t.root)

View File

@@ -0,0 +1,63 @@
class Node: # This is the Class Node with constructor that contains data variable to type data and left,right pointers.
def __init__(self, data):
self.data = data
self.left = None
self.right = None
def display(tree): #In Order traversal of the tree
if tree is None:
return
if tree.left is not None:
display(tree.left)
print(tree.data)
if tree.right is not None:
display(tree.right)
return
def depth_of_tree(tree): #This is the recursive function to find the depth of binary tree.
if tree is None:
return 0
else:
depth_l_tree = depth_of_tree(tree.left)
depth_r_tree = depth_of_tree(tree.right)
if depth_l_tree > depth_r_tree:
return 1 + depth_l_tree
else:
return 1 + depth_r_tree
def is_full_binary_tree(tree): # This functions returns that is it full binary tree or not?
if tree is None:
return True
if (tree.left is None) and (tree.right is None):
return True
if (tree.left is not None) and (tree.right is not None):
return (is_full_binary_tree(tree.left) and is_full_binary_tree(tree.right))
else:
return False
def main(): # Main func for testing.
tree = Node(1)
tree.left = Node(2)
tree.right = Node(3)
tree.left.left = Node(4)
tree.left.right = Node(5)
tree.left.right.left = Node(6)
tree.right.left = Node(7)
tree.right.left.left = Node(8)
tree.right.left.left.right = Node(9)
print(is_full_binary_tree(tree))
print(depth_of_tree(tree))
print("Tree is: ")
display(tree)
if __name__ == '__main__':
main()

View File

@@ -1,6 +0,0 @@
from .hash_table import HashTable
class QuadraticProbing(HashTable):
def __init__(self):
super(self.__class__, self).__init__()

View File

View File

View File

@@ -1,78 +0,0 @@
from __future__ import absolute_import
from .union_find import UnionFind
import unittest
class TestUnionFind(unittest.TestCase):
def test_init_with_valid_size(self):
uf = UnionFind(5)
self.assertEqual(uf.size, 5)
def test_init_with_invalid_size(self):
with self.assertRaises(ValueError):
uf = UnionFind(0)
with self.assertRaises(ValueError):
uf = UnionFind(-5)
def test_union_with_valid_values(self):
uf = UnionFind(10)
for i in range(11):
for j in range(11):
uf.union(i, j)
def test_union_with_invalid_values(self):
uf = UnionFind(10)
with self.assertRaises(ValueError):
uf.union(-1, 1)
with self.assertRaises(ValueError):
uf.union(11, 1)
def test_same_set_with_valid_values(self):
uf = UnionFind(10)
for i in range(11):
for j in range(11):
if i == j:
self.assertTrue(uf.same_set(i, j))
else:
self.assertFalse(uf.same_set(i, j))
uf.union(1, 2)
self.assertTrue(uf.same_set(1, 2))
uf.union(3, 4)
self.assertTrue(uf.same_set(3, 4))
self.assertFalse(uf.same_set(1, 3))
self.assertFalse(uf.same_set(1, 4))
self.assertFalse(uf.same_set(2, 3))
self.assertFalse(uf.same_set(2, 4))
uf.union(1, 3)
self.assertTrue(uf.same_set(1, 3))
self.assertTrue(uf.same_set(1, 4))
self.assertTrue(uf.same_set(2, 3))
self.assertTrue(uf.same_set(2, 4))
uf.union(4, 10)
self.assertTrue(uf.same_set(1, 10))
self.assertTrue(uf.same_set(2, 10))
self.assertTrue(uf.same_set(3, 10))
self.assertTrue(uf.same_set(4, 10))
def test_same_set_with_invalid_values(self):
uf = UnionFind(10)
with self.assertRaises(ValueError):
uf.same_set(-1, 1)
with self.assertRaises(ValueError):
uf.same_set(11, 0)
if __name__ == '__main__':
unittest.main()

View File

@@ -1,87 +0,0 @@
class UnionFind():
"""
https://en.wikipedia.org/wiki/Disjoint-set_data_structure
The union-find is a disjoint-set data structure
You can merge two sets and tell if one set belongs to
another one.
It's used on the Kruskal Algorithm
(https://en.wikipedia.org/wiki/Kruskal%27s_algorithm)
The elements are in range [0, size]
"""
def __init__(self, size):
if size <= 0:
raise ValueError("size should be greater than 0")
self.size = size
# The below plus 1 is because we are using elements
# in range [0, size]. It makes more sense.
# Every set begins with only itself
self.root = [i for i in range(size+1)]
# This is used for heuristic union by rank
self.weight = [0 for i in range(size+1)]
def union(self, u, v):
"""
Union of the sets u and v.
Complexity: log(n).
Amortized complexity: < 5 (it's very fast).
"""
self._validate_element_range(u, "u")
self._validate_element_range(v, "v")
if u == v:
return
# Using union by rank will guarantee the
# log(n) complexity
rootu = self._root(u)
rootv = self._root(v)
weight_u = self.weight[rootu]
weight_v = self.weight[rootv]
if weight_u >= weight_v:
self.root[rootv] = rootu
if weight_u == weight_v:
self.weight[rootu] += 1
else:
self.root[rootu] = rootv
def same_set(self, u, v):
"""
Return true if the elements u and v belongs to
the same set
"""
self._validate_element_range(u, "u")
self._validate_element_range(v, "v")
return self._root(u) == self._root(v)
def _root(self, u):
"""
Get the element set root.
This uses the heuristic path compression
See wikipedia article for more details.
"""
if u != self.root[u]:
self.root[u] = self._root(self.root[u])
return self.root[u]
def _validate_element_range(self, u, element_name):
"""
Raises ValueError if element is not in range
"""
if u < 0 or u > self.size:
msg = ("element {0} with value {1} "
"should be in range [0~{2}]")\
.format(element_name, u, self.size)
raise ValueError(msg)